From 2b2a3f5086d4eee2363193c685b74596d159c4b9 Mon Sep 17 00:00:00 2001 From: Mark Vieira Date: Thu, 4 Apr 2019 19:51:13 -0700 Subject: [PATCH] Replace usages RandomizedTestingTask with built-in Gradle Test (#40564) This commit replaces the existing RandomizedTestingTask and supporting code with Gradle's built-in JUnit support via the Test task type. Additionally, the previous workaround to disable all tasks named "test" and create new unit testing tasks named "unitTest" has been removed such that the "test" task now runs unit tests as per the normal Gradle Java plugin conventions --- benchmarks/build.gradle | 2 +- buildSrc/build.gradle | 15 +- .../junit4/BalancersConfiguration.groovy | 53 --- .../junit4/ListenersConfiguration.groovy | 25 -- .../junit4/RandomizedTestingPlugin.groovy | 60 --- .../junit4/RandomizedTestingTask.groovy | 330 ---------------- .../junit4/SlowTestsConfiguration.groovy | 14 - .../StackTraceFiltersConfiguration.groovy | 14 - .../junit4/TestLoggingConfiguration.groovy | 43 -- .../gradle/junit4/TestProgressLogger.groovy | 193 --------- .../gradle/junit4/TestReportLogger.groovy | 369 ------------------ .../elasticsearch/gradle/BuildPlugin.groovy | 265 +++++++------ .../gradle}/LoggingOutputStream.groovy | 2 +- .../gradle/test/RestIntegTestTask.groovy | 75 +++- .../test/StandaloneRestTestPlugin.groovy | 47 ++- .../gradle/test/StandaloneTestPlugin.groovy | 26 +- .../vagrant/TapLoggerOutputStream.groovy | 2 +- .../vagrant/VagrantLoggerOutputStream.groovy | 2 +- .../precommit/TestingConventionsTasks.java | 39 -- .../test/ErrorReportingTestListener.java | 180 +++++++++ .../testfixtures/TestFixturesPlugin.java | 28 +- ...carrotsearch.randomized-testing.properties | 1 - .../precommit/TestingConventionsTasksIT.java | 7 +- .../testKit/elasticsearch.build/build.gradle | 2 +- .../testKit/testingConventions/build.gradle | 14 +- client/benchmark/build.gradle | 2 +- .../build.gradle | 2 +- client/test/build.gradle | 2 +- .../archives/integ-test-zip/build.gradle | 2 +- .../tools/java-version-checker/build.gradle | 2 +- distribution/tools/plugin-cli/build.gradle | 2 +- libs/cli/build.gradle | 2 +- .../org/elasticsearch/bootstrap/JarHell.java | 27 +- libs/plugin-classloader/build.gradle | 2 +- modules/lang-painless/build.gradle | 4 +- modules/lang-painless/spi/build.gradle | 2 +- modules/reindex/build.gradle | 6 +- modules/transport-netty4/build.gradle | 2 +- plugins/discovery-ec2/build.gradle | 2 +- plugins/discovery-gce/build.gradle | 2 +- .../examples/custom-suggester/build.gradle | 2 +- .../examples/painless-whitelist/build.gradle | 2 +- plugins/examples/rest-handler/build.gradle | 4 +- .../script-expert-scoring/build.gradle | 2 +- plugins/repository-hdfs/build.gradle | 9 +- plugins/repository-s3/build.gradle | 5 +- qa/die-with-dignity/build.gradle | 6 +- qa/evil-tests/build.gradle | 2 +- qa/full-cluster-restart/build.gradle | 2 +- qa/logging-config/build.gradle | 4 +- qa/mixed-cluster/build.gradle | 2 +- qa/multi-cluster-search/build.gradle | 2 +- qa/rolling-upgrade/build.gradle | 2 +- qa/unconfigured-node-name/build.gradle | 2 +- qa/vagrant/build.gradle | 2 +- qa/verify-version-constants/build.gradle | 2 +- qa/wildfly/build.gradle | 2 +- rest-api-spec/build.gradle | 2 +- server/build.gradle | 13 +- .../bootstrap/test-framework.policy | 19 + test/fixtures/hdfs-fixture/build.gradle | 2 +- test/fixtures/krb5kdc-fixture/build.gradle | 2 +- test/fixtures/old-elasticsearch/build.gradle | 2 +- test/framework/build.gradle | 5 +- .../bootstrap/BootstrapForTesting.java | 10 +- .../junit/listeners/ReproduceInfoPrinter.java | 22 +- x-pack/plugin/ccr/build.gradle | 31 +- x-pack/plugin/ccr/qa/build.gradle | 2 +- .../downgrade-to-basic-license/build.gradle | 6 +- .../plugin/ccr/qa/multi-cluster/build.gradle | 8 +- .../ccr/qa/non-compliant-license/build.gradle | 4 +- x-pack/plugin/ccr/qa/rest/build.gradle | 2 +- x-pack/plugin/ccr/qa/restart/build.gradle | 6 +- x-pack/plugin/ccr/qa/security/build.gradle | 4 +- x-pack/plugin/core/build.gradle | 5 +- x-pack/plugin/ilm/qa/build.gradle | 2 +- .../plugin/ilm/qa/multi-cluster/build.gradle | 6 +- x-pack/plugin/ilm/qa/rest/build.gradle | 2 +- x-pack/plugin/ml/build.gradle | 13 +- x-pack/plugin/monitoring/build.gradle | 16 +- x-pack/plugin/security/build.gradle | 2 +- x-pack/plugin/security/cli/build.gradle | 2 +- x-pack/plugin/sql/build.gradle | 9 +- x-pack/plugin/sql/jdbc/build.gradle | 2 +- x-pack/plugin/sql/qa/build.gradle | 2 +- x-pack/plugin/sql/qa/security/build.gradle | 4 +- x-pack/plugin/sql/sql-cli/build.gradle | 2 +- x-pack/plugin/watcher/build.gradle | 2 +- x-pack/qa/evil-tests/build.gradle | 2 +- x-pack/qa/full-cluster-restart/build.gradle | 12 +- .../build.gradle | 2 +- x-pack/qa/rolling-upgrade-basic/build.gradle | 2 +- .../build.gradle | 62 +-- x-pack/qa/rolling-upgrade/build.gradle | 2 +- .../third-party/active-directory/build.gradle | 2 +- x-pack/test/idp-fixture/build.gradle | 2 +- x-pack/test/smb-fixture/build.gradle | 2 +- 97 files changed, 666 insertions(+), 1552 deletions(-) delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/BalancersConfiguration.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/ListenersConfiguration.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingPlugin.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingTask.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/SlowTestsConfiguration.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/StackTraceFiltersConfiguration.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestLoggingConfiguration.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestProgressLogger.groovy delete mode 100644 buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestReportLogger.groovy rename buildSrc/src/main/groovy/{com/carrotsearch/gradle/junit4 => org/elasticsearch/gradle}/LoggingOutputStream.groovy (97%) create mode 100644 buildSrc/src/main/java/org/elasticsearch/gradle/test/ErrorReportingTestListener.java delete mode 100644 buildSrc/src/main/resources/META-INF/gradle-plugins/carrotsearch.randomized-testing.properties diff --git a/benchmarks/build.gradle b/benchmarks/build.gradle index 351b0b9e97118..13eca8f06c26f 100644 --- a/benchmarks/build.gradle +++ b/benchmarks/build.gradle @@ -24,7 +24,7 @@ mainClassName = 'org.openjdk.jmh.Main' assemble.enabled = false archivesBaseName = 'elasticsearch-benchmarks' -unitTest.enabled = false +test.enabled = false dependencies { compile("org.elasticsearch:elasticsearch:${version}") { diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 9d25532d4cef1..ba512708e1977 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -199,15 +199,14 @@ if (project != rootProject) { into localDownloads } - unitTest { + test { // The test task is configured to runtimeJava version, but build-tools doesn't support all of them, so test // with compiler instead on the ones that are too old. if (project.runtimeJavaVersion <= JavaVersion.VERSION_1_10) { - jvm = "${project.compilerJavaHome}/bin/java" + executable = "${project.compilerJavaHome}/bin/java" } } - - // This can't be an RandomizedTestingTask because we can't yet reference it + task integTest(type: Test) { // integration test requires the local testing repo for example plugin builds dependsOn project.rootProject.allprojects.collect { @@ -215,8 +214,6 @@ if (project != rootProject) { } dependsOn setupLocalDownloads exclude "**/*Tests.class" - testClassesDirs = sourceSets.test.output.classesDirs - classpath = sourceSets.test.runtimeClasspath inputs.dir(file("src/testKit")) // tell BuildExamplePluginsIT where to find the example plugins systemProperty ( @@ -232,11 +229,7 @@ if (project != rootProject) { if (isLuceneSnapshot) { systemProperty 'test.lucene-snapshot-revision', isLuceneSnapshot[0][1] } - String defaultParallel = System.getProperty('tests.jvms', project.rootProject.ext.defaultParallel) - if (defaultParallel == "auto") { - defaultParallel = Math.max(Runtime.getRuntime().availableProcessors(), 4) - } - maxParallelForks defaultParallel as Integer + maxParallelForks System.getProperty('tests.jvms', project.rootProject.ext.defaultParallel.toString()) as Integer } check.dependsOn(integTest) diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/BalancersConfiguration.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/BalancersConfiguration.groovy deleted file mode 100644 index 91355bf2494cd..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/BalancersConfiguration.groovy +++ /dev/null @@ -1,53 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -import com.carrotsearch.ant.tasks.junit4.SuiteBalancer -import com.carrotsearch.ant.tasks.junit4.balancers.ExecutionTimeBalancer -import com.carrotsearch.ant.tasks.junit4.listeners.ExecutionTimesReport -import org.apache.tools.ant.types.FileSet - -class BalancersConfiguration { - // parent task, so executionTime can register an additional listener - RandomizedTestingTask task - List balancers = new ArrayList<>() - - void executionTime(Map properties) { - ExecutionTimeBalancer balancer = new ExecutionTimeBalancer() - - FileSet fileSet = new FileSet() - Object filename = properties.remove('cacheFilename') - if (filename == null) { - throw new IllegalArgumentException('cacheFilename is required for executionTime balancer') - } - fileSet.setIncludes(filename.toString()) - - File cacheDir = task.project.projectDir - Object dir = properties.remove('cacheDir') - if (dir != null) { - cacheDir = new File(dir.toString()) - } - fileSet.setDir(cacheDir) - balancer.add(fileSet) - - int historySize = 10 - Object size = properties.remove('historySize') - if (size instanceof Integer) { - historySize = (Integer)size - } else if (size != null) { - throw new IllegalArgumentException('historySize must be an integer') - } - ExecutionTimesReport listener = new ExecutionTimesReport() - listener.setFile(new File(cacheDir, filename.toString())) - listener.setHistoryLength(historySize) - - if (properties.isEmpty() == false) { - throw new IllegalArgumentException('Unknown properties for executionTime balancer: ' + properties.keySet()) - } - - task.listenersConfig.listeners.add(listener) - balancers.add(balancer) - } - - void custom(SuiteBalancer balancer) { - balancers.add(balancer) - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/ListenersConfiguration.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/ListenersConfiguration.groovy deleted file mode 100644 index 5fa5baa8ffb0c..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/ListenersConfiguration.groovy +++ /dev/null @@ -1,25 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener -import com.carrotsearch.ant.tasks.junit4.listeners.antxml.AntXmlReport - - -class ListenersConfiguration { - RandomizedTestingTask task - List listeners = new ArrayList<>() - - void junitReport(Map props) { - AntXmlReport reportListener = new AntXmlReport() - Object dir = props == null ? null : props.get('dir') - if (dir != null) { - reportListener.setDir(task.project.file(dir)) - } else { - reportListener.setDir(new File(task.project.buildDir, 'reports' + File.separator + "${task.name}Junit")) - } - listeners.add(reportListener) - } - - void custom(AggregatedEventListener listener) { - listeners.add(listener) - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingPlugin.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingPlugin.groovy deleted file mode 100644 index 7d554386c3920..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingPlugin.groovy +++ /dev/null @@ -1,60 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -import com.carrotsearch.ant.tasks.junit4.JUnit4 -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.tasks.TaskContainer - -class RandomizedTestingPlugin implements Plugin { - - void apply(Project project) { - String seed = setupSeed(project) - createUnitTestTask(project.tasks) - configureAnt(project.ant, seed) - } - - /** - * Pins the test seed at configuration time so it isn't different on every - * {@link RandomizedTestingTask} execution. This is useful if random - * decisions in one run of {@linkplain RandomizedTestingTask} influence the - * outcome of subsequent runs. Pinning the seed up front like this makes - * the reproduction line from one run be useful on another run. - */ - static String setupSeed(Project project) { - if (project.rootProject.ext.has('testSeed')) { - /* Skip this if we've already pinned the testSeed. It is important - * that this checks the rootProject so that we know we've only ever - * initialized one time. */ - return project.rootProject.ext.testSeed - } - String testSeed = System.getProperty('tests.seed') - if (testSeed == null) { - long seed = new Random(System.currentTimeMillis()).nextLong() - testSeed = Long.toUnsignedString(seed, 16).toUpperCase(Locale.ROOT) - } - /* Set the testSeed on the root project first so other projects can use - * it during initialization. */ - project.rootProject.ext.testSeed = testSeed - project.rootProject.subprojects { - project.ext.testSeed = testSeed - } - - return testSeed - } - - static void createUnitTestTask(TaskContainer tasks) { - // only create a unitTest task if the `test` task exists as some project don't make use of it. - tasks.matching { it.name == "test" }.all { - // We don't want to run any tests with the Gradle test runner since we add our own randomized runner - it.enabled = false - RandomizedTestingTask unitTest = tasks.create('unitTest', RandomizedTestingTask) - unitTest.description = 'Runs unit tests with the randomized testing framework' - it.dependsOn unitTest - } - } - - static void configureAnt(AntBuilder ant, String seed) { - ant.project.addTaskDefinition('junit4:junit4', JUnit4.class) - ant.properties.put('tests.seed', seed) - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingTask.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingTask.groovy deleted file mode 100644 index e5500d60093ed..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/RandomizedTestingTask.groovy +++ /dev/null @@ -1,330 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -import com.carrotsearch.ant.tasks.junit4.ListenersList -import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener -import groovy.xml.NamespaceBuilder -import groovy.xml.NamespaceBuilderSupport -import org.apache.tools.ant.BuildException -import org.apache.tools.ant.DefaultLogger -import org.apache.tools.ant.Project -import org.apache.tools.ant.RuntimeConfigurable -import org.apache.tools.ant.UnknownElement -import org.elasticsearch.gradle.BuildPlugin -import org.gradle.api.DefaultTask -import org.gradle.api.InvalidUserDataException -import org.gradle.api.file.FileCollection -import org.gradle.api.file.FileTreeElement -import org.gradle.api.specs.Spec -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.options.Option -import org.gradle.api.tasks.util.PatternFilterable -import org.gradle.api.tasks.util.PatternSet -import org.gradle.internal.logging.progress.ProgressLoggerFactory -import org.gradle.util.ConfigureUtil - -import javax.inject.Inject - -class RandomizedTestingTask extends DefaultTask { - - // TODO: change to "executable" to match gradle test params? - @Optional - @Input - String jvm = 'java' - - @Optional - @Input - File workingDir = new File(project.buildDir, 'testrun' + File.separator + name) - - @Optional - @Input - FileCollection classpath - - @Input - String parallelism = '1' - - @Input - FileCollection testClassesDirs - - @Optional - @Input - boolean haltOnFailure = true - - @Optional - @Input - boolean shuffleOnSlave = true - - @Optional - @Input - boolean enableAssertions = true - - @Optional - @Input - boolean enableSystemAssertions = true - - @Optional - @Input - boolean leaveTemporary = false - - @Optional - @Input - String ifNoTests = 'ignore' - - @Optional - @Input - String onNonEmptyWorkDirectory = 'fail' - - TestLoggingConfiguration testLoggingConfig = new TestLoggingConfiguration() - - BalancersConfiguration balancersConfig = new BalancersConfiguration(task: this) - ListenersConfiguration listenersConfig = new ListenersConfiguration(task: this) - - List jvmArgs = new ArrayList<>() - - @Optional - @Input - String argLine = null - - Map systemProperties = new HashMap<>() - Map environmentVariables = new HashMap<>() - PatternFilterable patternSet = new PatternSet() - - RandomizedTestingTask() { - outputs.upToDateWhen {false} // randomized tests are never up to date - listenersConfig.listeners.add(new TestProgressLogger(factory: getProgressLoggerFactory())) - listenersConfig.listeners.add(new TestReportLogger(logger: logger, config: testLoggingConfig)) - } - - @Inject - ProgressLoggerFactory getProgressLoggerFactory() { - throw new UnsupportedOperationException() - } - - void jvmArgs(Iterable arguments) { - jvmArgs.addAll(arguments) - } - - void jvmArg(String argument) { - jvmArgs.add(argument) - } - - void systemProperty(String property, Object value) { - systemProperties.put(property, value) - } - - void environment(String key, Object value) { - environmentVariables.put(key, value) - } - - void include(String... includes) { - this.patternSet.include(includes); - } - - void include(Iterable includes) { - this.patternSet.include(includes); - } - - void include(Spec includeSpec) { - this.patternSet.include(includeSpec); - } - - void include(Closure includeSpec) { - this.patternSet.include(includeSpec); - } - - void exclude(String... excludes) { - this.patternSet.exclude(excludes); - } - - void exclude(Iterable excludes) { - this.patternSet.exclude(excludes); - } - - void exclude(Spec excludeSpec) { - this.patternSet.exclude(excludeSpec); - } - - void exclude(Closure excludeSpec) { - this.patternSet.exclude(excludeSpec); - } - - @Input - void testLogging(Closure closure) { - ConfigureUtil.configure(closure, testLoggingConfig) - } - - @Input - void balancers(Closure closure) { - ConfigureUtil.configure(closure, balancersConfig) - } - - @Input - void listeners(Closure closure) { - ConfigureUtil.configure(closure, listenersConfig) - } - - @Option( - option = "tests", - description = "Sets test class or method name to be included. This is for IDEs. Use -Dtests.class and -Dtests.method" - ) - void setTestNameIncludePattern(String testNamePattern) { - // This is only implemented to give support for IDEs running tests. There are 3 patterns expected: - // * An exact test class and method - // * An exact test class - // * A package name prefix, ending with .* - // There is no way to distinguish the first two without looking at classes, so we use the rule - // that class names start with an uppercase letter... - // TODO: this doesn't work yet, but not sure why...intellij says it is using --tests, and this work from the command line... - String[] parts = testNamePattern.split('\\.') - String lastPart = parts[parts.length - 1] - String classname - String methodname = null - if (lastPart.equals('*') || lastPart.charAt(0).isUpperCase()) { - // package name or class name, just pass through - classname = testNamePattern - } else { - // method name, need to separate - methodname = lastPart - classname = testNamePattern.substring(0, testNamePattern.length() - lastPart.length() - 1) - } - ant.setProperty('tests.class', classname) - if (methodname != null) { - ant.setProperty('tests.method', methodname) - } - } - - @TaskAction - void executeTests() { - Map attributes = [ - jvm: jvm, - parallelism: parallelism, - heartbeat: testLoggingConfig.slowTests.heartbeat, - dir: workingDir, - tempdir: new File(workingDir, 'temp'), - haltOnFailure: true, // we want to capture when a build failed, but will decide whether to rethrow later - shuffleOnSlave: shuffleOnSlave, - leaveTemporary: leaveTemporary, - ifNoTests: ifNoTests, - onNonEmptyWorkDirectory: onNonEmptyWorkDirectory, - newenvironment: true - ] - - DefaultLogger listener = null - ByteArrayOutputStream antLoggingBuffer = null - if (logger.isInfoEnabled() == false) { - // in info logging, ant already outputs info level, so we see everything - // but on errors or when debugging, we want to see info level messages - // because junit4 emits jvm output with ant logging - if (testLoggingConfig.outputMode == TestLoggingConfiguration.OutputMode.ALWAYS) { - // we want all output, so just stream directly - listener = new DefaultLogger( - errorPrintStream: System.err, - outputPrintStream: System.out, - messageOutputLevel: Project.MSG_INFO) - } else { - // we want to buffer the info, and emit it if the test fails - antLoggingBuffer = new ByteArrayOutputStream() - PrintStream stream = new PrintStream(antLoggingBuffer, true, "UTF-8") - listener = new DefaultLogger( - errorPrintStream: stream, - outputPrintStream: stream, - messageOutputLevel: Project.MSG_INFO) - } - project.ant.project.addBuildListener(listener) - } - - NamespaceBuilderSupport junit4 = NamespaceBuilder.newInstance(ant, 'junit4') - try { - junit4.junit4(attributes) { - classpath { - pathElement(path: classpath.asPath) - } - if (enableAssertions) { - jvmarg(value: '-ea') - } - if (enableSystemAssertions) { - jvmarg(value: '-esa') - } - for (String arg : jvmArgs) { - jvmarg(value: arg) - } - if (argLine != null) { - jvmarg(line: argLine) - } - testClassesDirs.each { testClassDir -> - fileset(dir: testClassDir) { - patternSet.getIncludes().each { include(name: it) } - patternSet.getExcludes().each { exclude(name: it) } - } - } - for (Map.Entry prop : systemProperties) { - if (prop.getKey().equals('tests.seed')) { - throw new InvalidUserDataException('Seed should be ' + - 'set on the project instead of a system property') - } - if (prop.getValue() instanceof Closure) { - sysproperty key: prop.getKey(), value: (prop.getValue() as Closure).call().toString() - } else { - sysproperty key: prop.getKey(), value: prop.getValue().toString() - } - } - systemProperty 'tests.seed', project.testSeed - for (Map.Entry envvar : environmentVariables) { - env key: envvar.getKey(), value: envvar.getValue().toString() - } - makeListeners() - } - } catch (BuildException e) { - if (antLoggingBuffer != null) { - logger.error('JUnit4 test failed, ant output was:') - logger.error(antLoggingBuffer.toString('UTF-8')) - } - if (haltOnFailure) { - throw e; - } - } - - if (listener != null) { - // remove the listener we added so other ant tasks dont have verbose logging! - project.ant.project.removeBuildListener(listener) - } - } - - static class ListenersElement extends UnknownElement { - AggregatedEventListener[] listeners - - ListenersElement() { - super('listeners') - setNamespace('junit4') - setQName('listeners') - } - - public void handleChildren(Object realThing, RuntimeConfigurable wrapper) { - assert realThing instanceof ListenersList - ListenersList list = (ListenersList)realThing - - for (AggregatedEventListener listener : listeners) { - list.addConfigured(listener) - } - } - } - - /** - * Makes an ant xml element for 'listeners' just as AntBuilder would, except configuring - * the element adds the already created children. - */ - def makeListeners() { - def context = ant.getAntXmlContext() - def parentWrapper = context.currentWrapper() - def parent = parentWrapper.getProxy() - UnknownElement element = new ListenersElement(listeners: listenersConfig.listeners) - element.setProject(context.getProject()) - element.setRealThing(logger) - ((UnknownElement)parent).addChild(element) - RuntimeConfigurable wrapper = new RuntimeConfigurable(element, element.getQName()) - parentWrapper.addChild(wrapper) - return wrapper.getProxy() - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/SlowTestsConfiguration.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/SlowTestsConfiguration.groovy deleted file mode 100644 index 2705fdeaacb35..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/SlowTestsConfiguration.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -class SlowTestsConfiguration { - int heartbeat = 0 - int summarySize = 0 - - void heartbeat(int heartbeat) { - this.heartbeat = heartbeat - } - - void summarySize(int summarySize) { - this.summarySize = summarySize - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/StackTraceFiltersConfiguration.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/StackTraceFiltersConfiguration.groovy deleted file mode 100644 index 5e5610ab68e52..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/StackTraceFiltersConfiguration.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -class StackTraceFiltersConfiguration { - List patterns = new ArrayList<>() - List contains = new ArrayList<>() - - void regex(String pattern) { - patterns.add(pattern) - } - - void contains(String contain) { - contains.add(contain) - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestLoggingConfiguration.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestLoggingConfiguration.groovy deleted file mode 100644 index 97251252f54e2..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestLoggingConfiguration.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -import org.gradle.api.tasks.Input -import org.gradle.util.ConfigureUtil - -class TestLoggingConfiguration { - /** Display mode for output streams. */ - static enum OutputMode { - /** Always display the output emitted from tests. */ - ALWAYS, - /** - * Display the output only if a test/ suite failed. This requires internal buffering - * so the output will be shown only after a test completes. - */ - ONERROR, - /** Don't display the output, even on test failures. */ - NEVER - } - - OutputMode outputMode = OutputMode.ONERROR - SlowTestsConfiguration slowTests = new SlowTestsConfiguration() - StackTraceFiltersConfiguration stackTraceFilters = new StackTraceFiltersConfiguration() - - /** Summarize the first N failures at the end of the test. */ - @Input - int showNumFailuresAtEnd = 3 // match TextReport default - - void slowTests(Closure closure) { - ConfigureUtil.configure(closure, slowTests) - } - - void stackTraceFilters(Closure closure) { - ConfigureUtil.configure(closure, stackTraceFilters) - } - - void outputMode(String mode) { - outputMode = mode.toUpperCase() as OutputMode - } - - void showNumFailuresAtEnd(int n) { - showNumFailuresAtEnd = n - } -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestProgressLogger.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestProgressLogger.groovy deleted file mode 100644 index 05248fc581e96..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestProgressLogger.groovy +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.carrotsearch.gradle.junit4 - -import com.carrotsearch.ant.tasks.junit4.JUnit4 -import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.eventbus.Subscribe -import com.carrotsearch.ant.tasks.junit4.events.TestStartedEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedQuitEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedStartEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteStartedEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedTestResultEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.ChildBootstrap -import com.carrotsearch.ant.tasks.junit4.events.aggregated.HeartBeatEvent -import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener -import org.gradle.internal.logging.progress.ProgressLogger -import org.gradle.internal.logging.progress.ProgressLoggerFactory -import org.junit.runner.Description - -import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatDurationInSeconds -import static com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus.ERROR -import static com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus.FAILURE -import static com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus.IGNORED -import static com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus.IGNORED_ASSUMPTION -import static com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus.OK - -/** - * Adapts junit4's event listeners into gradle's ProgressLogger. Note that - * junit4 guarantees (via guava) that methods on this class won't be called by - * multiple threads simultaneously which is helpful in making it simpler. - * - * Every time a test finishes this class will update the logger. It will log - * the last finished test method on the logger line until the first suite - * finishes. Once the first suite finishes it always logs the last finished - * suite. This means that in test runs with a single suite the logger will be - * updated with the test name the whole time which is useful because these runs - * usually have longer individual tests. For test runs with lots of suites the - * majority of the time is spent showing the last suite that finished which is - * more useful for those test runs because test methods there tend to be very - * quick. - */ -class TestProgressLogger implements AggregatedEventListener { - /** Factory to build a progress logger when testing starts */ - ProgressLoggerFactory factory - ProgressLogger parentProgressLogger - ProgressLogger suiteLogger - ProgressLogger testLogger - ProgressLogger[] slaveLoggers - int totalSuites - int totalSlaves - - // Counters incremented test completion. - volatile int suitesCompleted = 0 - volatile int testsCompleted = 0 - volatile int testsFailed = 0 - volatile int testsIgnored = 0 - - @Subscribe - void onStart(AggregatedStartEvent e) throws IOException { - totalSuites = e.suiteCount - totalSlaves = e.slaveCount - parentProgressLogger = factory.newOperation(TestProgressLogger) - parentProgressLogger.setDescription('Randomized test runner') - parentProgressLogger.started() - - suiteLogger = factory.newOperation(TestProgressLogger, parentProgressLogger) - suiteLogger.setDescription('Suite logger') - suiteLogger.started("Suites: 0/" + totalSuites) - testLogger = factory.newOperation(TestProgressLogger, parentProgressLogger) - testLogger.setDescription('Test logger') - testLogger.started('Tests: completed: 0, failed: 0, ignored: 0') - slaveLoggers = new ProgressLogger[e.slaveCount] - for (int i = 0; i < e.slaveCount; ++i) { - slaveLoggers[i] = factory.newOperation(TestProgressLogger, parentProgressLogger) - slaveLoggers[i].setDescription("J${i} test logger") - slaveLoggers[i].started("J${i}: initializing...") - } - } - - @Subscribe - void onChildBootstrap(ChildBootstrap e) throws IOException { - slaveLoggers[e.getSlave().id].progress("J${e.slave.id}: starting (pid ${e.slave.pidString})") - } - - @Subscribe - void onQuit(AggregatedQuitEvent e) throws IOException { - // if onStart was never called (eg no matching tests), suiteLogger and all the other loggers will be null - if (suiteLogger != null) { - suiteLogger.completed() - testLogger.completed() - for (ProgressLogger slaveLogger : slaveLoggers) { - slaveLogger.completed() - } - parentProgressLogger.completed() - } - } - - @Subscribe - void onSuiteStart(AggregatedSuiteStartedEvent e) throws IOException { - String suiteName = simpleName(e.suiteStartedEvent.description) - slaveLoggers[e.slave.id].progress("J${e.slave.id}: ${suiteName} - initializing") - } - - @Subscribe - void onSuiteResult(AggregatedSuiteResultEvent e) throws IOException { - suitesCompleted++ - suiteLogger.progress("Suites: " + suitesCompleted + "/" + totalSuites) - } - - @Subscribe - void onTestResult(AggregatedTestResultEvent e) throws IOException { - String statusMessage - testsCompleted++ - switch (e.status) { - case ERROR: - case FAILURE: - testsFailed++ - statusMessage = "failed" - break - case IGNORED: - case IGNORED_ASSUMPTION: - testsIgnored++ - statusMessage = "ignored" - break - case OK: - String time = formatDurationInSeconds(e.executionTime) - statusMessage = "completed [${time}]" - break - default: - throw new IllegalArgumentException("Unknown test status: [${e.status}]") - } - testLogger.progress("Tests: completed: ${testsCompleted}, failed: ${testsFailed}, ignored: ${testsIgnored}") - String testName = testName(e.description) - slaveLoggers[e.slave.id].progress("J${e.slave.id}: ${testName} ${statusMessage}") - } - - @Subscribe - void onTestStarted(TestStartedEvent e) throws IOException { - String testName = testName(e.description) - slaveLoggers[e.slave.id].progress("J${e.slave.id}: ${testName} ...") - } - - @Subscribe - void onHeartbeat(HeartBeatEvent e) throws IOException { - String testName = testName(e.description) - String time = formatDurationInSeconds(e.getNoEventDuration()) - slaveLoggers[e.slave.id].progress("J${e.slave.id}: ${testName} stalled for ${time}") - } - - /** - * Build the test name in the format of . - */ - private static String testName(Description description) { - String className = simpleName(description) - if (description == null) { - return className + "." + "" - } - return className + "." + description.methodName - } - - /** - * Extract a Class#getSimpleName style name from Class#getName style - * string. We can't just use Class#getSimpleName because junit descriptions - * don't always set the class field but they always set the className - * field. - */ - private static String simpleName(Description description) { - if (description == null) { - return "" - } - return description.className.substring(description.className.lastIndexOf('.') + 1) - } - - @Override - void setOuter(JUnit4 junit) {} -} diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestReportLogger.groovy b/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestReportLogger.groovy deleted file mode 100644 index 6ed6ecf86196d..0000000000000 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/TestReportLogger.groovy +++ /dev/null @@ -1,369 +0,0 @@ -package com.carrotsearch.gradle.junit4 - -import com.carrotsearch.ant.tasks.junit4.JUnit4 -import com.carrotsearch.ant.tasks.junit4.Pluralize -import com.carrotsearch.ant.tasks.junit4.TestsSummaryEventListener -import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.base.Strings -import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.eventbus.Subscribe -import com.carrotsearch.ant.tasks.junit4.events.EventType -import com.carrotsearch.ant.tasks.junit4.events.IEvent -import com.carrotsearch.ant.tasks.junit4.events.IStreamEvent -import com.carrotsearch.ant.tasks.junit4.events.SuiteStartedEvent -import com.carrotsearch.ant.tasks.junit4.events.TestFinishedEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedQuitEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedResultEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedStartEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteResultEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedSuiteStartedEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.AggregatedTestResultEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.ChildBootstrap -import com.carrotsearch.ant.tasks.junit4.events.aggregated.HeartBeatEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.PartialOutputEvent -import com.carrotsearch.ant.tasks.junit4.events.aggregated.TestStatus -import com.carrotsearch.ant.tasks.junit4.events.mirrors.FailureMirror -import com.carrotsearch.ant.tasks.junit4.listeners.AggregatedEventListener -import com.carrotsearch.ant.tasks.junit4.listeners.StackTraceFilter -import org.apache.tools.ant.filters.TokenFilter -import org.gradle.api.logging.LogLevel -import org.gradle.api.logging.Logger -import org.junit.runner.Description - -import java.util.concurrent.atomic.AtomicInteger - -import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatDescription -import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatDurationInSeconds -import static com.carrotsearch.ant.tasks.junit4.FormattingUtils.formatTime -import static com.carrotsearch.gradle.junit4.TestLoggingConfiguration.OutputMode - -class TestReportLogger extends TestsSummaryEventListener implements AggregatedEventListener { - - static final String FAILURE_MARKER = " <<< FAILURES!" - - /** Status names column. */ - static EnumMap statusNames; - static { - statusNames = new EnumMap<>(TestStatus.class); - for (TestStatus s : TestStatus.values()) { - statusNames.put(s, - s == TestStatus.IGNORED_ASSUMPTION - ? "IGNOR/A" : s.toString()); - } - } - - JUnit4 owner - - /** Logger to write the report to */ - Logger logger - - TestLoggingConfiguration config - - /** Forked concurrent JVM count. */ - int forkedJvmCount - - /** Format line for JVM ID string. */ - String jvmIdFormat - - /** Output stream that logs messages to the given logger */ - LoggingOutputStream outStream - LoggingOutputStream errStream - - /** A list of failed tests, if to be displayed at the end. */ - List failedTests = new ArrayList<>() - - /** Stack trace filters. */ - StackTraceFilter stackFilter = new StackTraceFilter() - - Map suiteTimes = new HashMap<>() - boolean slowTestsFound = false - - int totalSuites - AtomicInteger suitesCompleted = new AtomicInteger() - - @Subscribe - void onStart(AggregatedStartEvent e) throws IOException { - this.totalSuites = e.getSuiteCount(); - StringBuilder info = new StringBuilder('==> Test Info: ') - info.append('seed=' + owner.getSeed() + '; ') - info.append(Pluralize.pluralize(e.getSlaveCount(), 'jvm') + '=' + e.getSlaveCount() + '; ') - info.append(Pluralize.pluralize(e.getSuiteCount(), 'suite') + '=' + e.getSuiteCount()) - logger.lifecycle(info.toString()) - - forkedJvmCount = e.getSlaveCount(); - jvmIdFormat = " J%-" + (1 + (int) Math.floor(Math.log10(forkedJvmCount))) + "d"; - - outStream = new LoggingOutputStream(logger: logger, level: LogLevel.LIFECYCLE, prefix: " 1> ") - errStream = new LoggingOutputStream(logger: logger, level: LogLevel.ERROR, prefix: " 2> ") - - for (String contains : config.stackTraceFilters.contains) { - TokenFilter.ContainsString containsFilter = new TokenFilter.ContainsString() - containsFilter.setContains(contains) - stackFilter.addContainsString(containsFilter) - } - for (String pattern : config.stackTraceFilters.patterns) { - TokenFilter.ContainsRegex regexFilter = new TokenFilter.ContainsRegex() - regexFilter.setPattern(pattern) - stackFilter.addContainsRegex(regexFilter) - } - } - - @Subscribe - void onChildBootstrap(ChildBootstrap e) throws IOException { - logger.info("Started J" + e.getSlave().id + " PID(" + e.getSlave().getPidString() + ")."); - } - - @Subscribe - void onHeartbeat(HeartBeatEvent e) throws IOException { - logger.warn("HEARTBEAT J" + e.getSlave().id + " PID(" + e.getSlave().getPidString() + "): " + - formatTime(e.getCurrentTime()) + ", stalled for " + - formatDurationInSeconds(e.getNoEventDuration()) + " at: " + - (e.getDescription() == null ? "" : formatDescription(e.getDescription()))) - slowTestsFound = true - } - - @Subscribe - void onQuit(AggregatedQuitEvent e) throws IOException { - if (config.showNumFailuresAtEnd > 0 && !failedTests.isEmpty()) { - List sublist = this.failedTests - StringBuilder b = new StringBuilder() - b.append('Tests with failures') - if (sublist.size() > config.showNumFailuresAtEnd) { - sublist = sublist.subList(0, config.showNumFailuresAtEnd) - b.append(" (first " + config.showNumFailuresAtEnd + " out of " + failedTests.size() + ")") - } - b.append(':\n') - for (Description description : sublist) { - b.append(" - ").append(formatDescription(description, true)).append('\n') - } - logger.warn(b.toString()) - } - if (config.slowTests.summarySize > 0) { - List> sortedSuiteTimes = new ArrayList<>(suiteTimes.entrySet()) - Collections.sort(sortedSuiteTimes, new Comparator>() { - @Override - int compare(Map.Entry o1, Map.Entry o2) { - return o2.value - o1.value // sort descending - } - }) - LogLevel level = slowTestsFound ? LogLevel.WARN : LogLevel.INFO - int numToLog = Math.min(config.slowTests.summarySize, sortedSuiteTimes.size()) - logger.log(level, 'Slow Tests Summary:') - for (int i = 0; i < numToLog; ++i) { - logger.log(level, String.format(Locale.ENGLISH, '%6.2fs | %s', - sortedSuiteTimes.get(i).value / 1000.0, - sortedSuiteTimes.get(i).key)); - } - logger.log(level, '') // extra vertical separation - } - if (failedTests.isEmpty()) { - // summary is already printed for failures - logger.lifecycle('==> Test Summary: ' + getResult().toString()) - } - } - - @Subscribe - void onSuiteStart(AggregatedSuiteStartedEvent e) throws IOException { - if (isPassthrough()) { - SuiteStartedEvent evt = e.getSuiteStartedEvent(); - emitSuiteStart(LogLevel.LIFECYCLE, evt.getDescription()); - } - } - - @Subscribe - void onOutput(PartialOutputEvent e) throws IOException { - if (isPassthrough()) { - // We only allow passthrough output if there is one JVM. - switch (e.getEvent().getType()) { - case EventType.APPEND_STDERR: - ((IStreamEvent) e.getEvent()).copyTo(errStream); - break; - case EventType.APPEND_STDOUT: - ((IStreamEvent) e.getEvent()).copyTo(outStream); - break; - default: - break; - } - } - } - - @Subscribe - void onTestResult(AggregatedTestResultEvent e) throws IOException { - if (isPassthrough() && e.getStatus() != TestStatus.OK) { - flushOutput(); - emitStatusLine(LogLevel.ERROR, e, e.getStatus(), e.getExecutionTime()); - } - - if (!e.isSuccessful()) { - failedTests.add(e.getDescription()); - } - } - - @Subscribe - void onSuiteResult(AggregatedSuiteResultEvent e) throws IOException { - final int completed = suitesCompleted.incrementAndGet(); - - if (e.isSuccessful() && e.getTests().isEmpty()) { - return; - } - if (config.slowTests.summarySize > 0) { - suiteTimes.put(e.getDescription().getDisplayName(), e.getExecutionTime()) - } - - LogLevel level = e.isSuccessful() && config.outputMode != OutputMode.ALWAYS ? LogLevel.INFO : LogLevel.LIFECYCLE - - // We must emit buffered test and stream events (in case of failures). - if (!isPassthrough()) { - emitSuiteStart(level, e.getDescription()) - emitBufferedEvents(level, e) - } - - // Emit a synthetic failure for suite-level errors, if any. - if (!e.getFailures().isEmpty()) { - emitStatusLine(level, e, TestStatus.ERROR, 0) - } - - if (!e.getFailures().isEmpty()) { - failedTests.add(e.getDescription()) - } - - emitSuiteEnd(level, e, completed) - } - - /** Suite prologue. */ - void emitSuiteStart(LogLevel level, Description description) throws IOException { - logger.log(level, 'Suite: ' + description.getDisplayName()); - } - - void emitBufferedEvents(LogLevel level, AggregatedSuiteResultEvent e) throws IOException { - if (config.outputMode == OutputMode.NEVER) { - return - } - - final IdentityHashMap eventMap = new IdentityHashMap<>(); - for (AggregatedTestResultEvent tre : e.getTests()) { - eventMap.put(tre.getTestFinishedEvent(), tre) - } - - final boolean emitOutput = config.outputMode == OutputMode.ALWAYS && isPassthrough() == false || - config.outputMode == OutputMode.ONERROR && e.isSuccessful() == false - - for (IEvent event : e.getEventStream()) { - switch (event.getType()) { - case EventType.APPEND_STDOUT: - if (emitOutput) ((IStreamEvent) event).copyTo(outStream); - break; - - case EventType.APPEND_STDERR: - if (emitOutput) ((IStreamEvent) event).copyTo(errStream); - break; - - case EventType.TEST_FINISHED: - assert eventMap.containsKey(event) - final AggregatedTestResultEvent aggregated = eventMap.get(event); - if (aggregated.getStatus() != TestStatus.OK) { - flushOutput(); - emitStatusLine(level, aggregated, aggregated.getStatus(), aggregated.getExecutionTime()); - } - - default: - break; - } - } - - if (emitOutput) { - flushOutput() - } - } - - void emitSuiteEnd(LogLevel level, AggregatedSuiteResultEvent e, int suitesCompleted) throws IOException { - - final StringBuilder b = new StringBuilder(); - b.append(String.format(Locale.ENGLISH, 'Completed [%d/%d]%s in %.2fs, ', - suitesCompleted, - totalSuites, - e.getSlave().slaves > 1 ? ' on J' + e.getSlave().id : '', - e.getExecutionTime() / 1000.0d)); - b.append(e.getTests().size()).append(Pluralize.pluralize(e.getTests().size(), ' test')); - - int failures = e.getFailureCount(); - if (failures > 0) { - b.append(', ').append(failures).append(Pluralize.pluralize(failures, ' failure')); - } - - int errors = e.getErrorCount(); - if (errors > 0) { - b.append(', ').append(errors).append(Pluralize.pluralize(errors, ' error')); - } - - int ignored = e.getIgnoredCount(); - if (ignored > 0) { - b.append(', ').append(ignored).append(' skipped'); - } - - if (!e.isSuccessful()) { - b.append(' <<< FAILURES!'); - } - - b.append('\n') - logger.log(level, b.toString()); - } - - /** Emit status line for an aggregated event. */ - void emitStatusLine(LogLevel level, AggregatedResultEvent result, TestStatus status, long timeMillis) throws IOException { - final StringBuilder line = new StringBuilder(); - - line.append(Strings.padEnd(statusNames.get(status), 8, ' ' as char)) - line.append(formatDurationInSeconds(timeMillis)) - if (forkedJvmCount > 1) { - line.append(String.format(Locale.ENGLISH, jvmIdFormat, result.getSlave().id)) - } - line.append(' | ') - - line.append(formatDescription(result.getDescription())) - if (!result.isSuccessful()) { - line.append(FAILURE_MARKER) - } - logger.log(level, line.toString()) - - PrintWriter writer = new PrintWriter(new LoggingOutputStream(logger: logger, level: level, prefix: ' > ')) - - if (status == TestStatus.IGNORED && result instanceof AggregatedTestResultEvent) { - writer.write('Cause: ') - writer.write(((AggregatedTestResultEvent) result).getCauseForIgnored()) - writer.flush() - } - - final List failures = result.getFailures(); - if (!failures.isEmpty()) { - int count = 0; - for (FailureMirror fm : failures) { - count++; - if (fm.isAssumptionViolation()) { - writer.write(String.format(Locale.ENGLISH, - 'Assumption #%d: %s', - count, fm.getMessage() == null ? '(no message)' : fm.getMessage())); - } else { - writer.write(String.format(Locale.ENGLISH, - 'Throwable #%d: %s', - count, - stackFilter.apply(fm.getTrace()))); - } - } - writer.flush() - } - } - - void flushOutput() throws IOException { - outStream.flush() - errStream.flush() - } - - /** Returns true if output should be logged immediately. */ - boolean isPassthrough() { - return forkedJvmCount == 1 && config.outputMode == OutputMode.ALWAYS - } - - @Override - void setOuter(JUnit4 task) { - owner = task - } -} diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy index 8a0e7a05327b4..04e000e2e4366 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy @@ -18,13 +18,13 @@ */ package org.elasticsearch.gradle -import com.carrotsearch.gradle.junit4.RandomizedTestingTask import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin import org.apache.commons.io.IOUtils import org.apache.tools.ant.taskdefs.condition.Os import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.lib.RepositoryBuilder import org.elasticsearch.gradle.precommit.PrecommitTasks +import org.elasticsearch.gradle.test.ErrorReportingTestListener import org.gradle.api.GradleException import org.gradle.api.InvalidUserDataException import org.gradle.api.JavaVersion @@ -40,8 +40,8 @@ import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.artifacts.ResolvedArtifact import org.gradle.api.artifacts.dsl.RepositoryHandler import org.gradle.api.credentials.HttpHeaderCredentials +import org.gradle.api.execution.TaskActionListener import org.gradle.api.execution.TaskExecutionGraph -import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaPlugin import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.plugins.MavenPublishPlugin @@ -51,6 +51,7 @@ import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.compile.GroovyCompile import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.javadoc.Javadoc +import org.gradle.api.tasks.testing.Test import org.gradle.authentication.http.HttpHeaderAuthentication import org.gradle.internal.jvm.Jvm import org.gradle.process.ExecResult @@ -83,7 +84,6 @@ class BuildPlugin implements Plugin { ) } project.pluginManager.apply('java') - project.pluginManager.apply('carrotsearch.randomized-testing') configureConfigurations(project) configureJars(project) // jar config must be added before info broker // these plugins add lots of info to our jars @@ -93,8 +93,12 @@ class BuildPlugin implements Plugin { project.pluginManager.apply('nebula.info-scm') project.pluginManager.apply('nebula.info-jar') + // apply global test task failure listener + project.rootProject.pluginManager.apply(TestFailureReportingPlugin) + project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask) + setupSeed(project) globalBuildInfo(project) configureRepositories(project) project.ext.versions = VersionProperties.versions @@ -103,9 +107,7 @@ class BuildPlugin implements Plugin { configureJavadoc(project) configureSourcesJar(project) configurePomGeneration(project) - - applyCommonTestConfig(project) - configureTest(project) + configureTestTasks(project) configurePrecommit(project) configureDependenciesInfo(project) } @@ -904,128 +906,108 @@ class BuildPlugin implements Plugin { } } - static void applyCommonTestConfig(Project project) { - project.tasks.withType(RandomizedTestingTask) {task -> - jvm "${project.runtimeJavaHome}/bin/java" - parallelism System.getProperty('tests.jvms', project.rootProject.ext.defaultParallel) - ifNoTests 'fail' - onNonEmptyWorkDirectory 'wipe' - leaveTemporary true - project.sourceSets.matching { it.name == "test" }.all { test -> - task.testClassesDirs = test.output.classesDirs - task.classpath = test.runtimeClasspath - } - group = JavaBasePlugin.VERIFICATION_GROUP - dependsOn 'testClasses' + static void configureTestTasks(Project project) { + // Default test task should run only unit tests + project.tasks.withType(Test).matching { it.name == 'test' }.all { + include '**/*Tests.class' + } + + // none of this stuff is applicable to the `:buildSrc` project tests + if (project.path != ':build-tools') { + File heapdumpDir = new File(project.buildDir, 'heapdump') - // Make sure all test tasks are configured properly - if (name != "test") { - project.tasks.matching { it.name == "test"}.all { testTask -> - task.shouldRunAfter testTask + project.tasks.withType(Test) { Test test -> + doFirst { + heapdumpDir.mkdirs() + workingDir.mkdirs() } - } - if (name == "unitTest") { - include("**/*Tests.class") - } - // TODO: why are we not passing maxmemory to junit4? - jvmArg '-Xmx' + System.getProperty('tests.heap.size', '512m') - jvmArg '-Xms' + System.getProperty('tests.heap.size', '512m') - jvmArg '-XX:+HeapDumpOnOutOfMemoryError' - File heapdumpDir = new File(project.buildDir, 'heapdump') - heapdumpDir.mkdirs() - jvmArg '-XX:HeapDumpPath=' + heapdumpDir - if (project.runtimeJavaVersion >= JavaVersion.VERSION_1_9) { - jvmArg '--illegal-access=warn' - } - argLine System.getProperty('tests.jvm.argline') - - // we use './temp' since this is per JVM and tests are forbidden from writing to CWD - systemProperty 'java.io.tmpdir', './temp' - systemProperty 'java.awt.headless', 'true' - systemProperty 'tests.gradle', 'true' - systemProperty 'tests.artifact', project.name - systemProperty 'tests.task', path - systemProperty 'tests.security.manager', 'true' - systemProperty 'jna.nosys', 'true' - systemProperty 'compiler.java', project.ext.compilerJavaVersion.getMajorVersion() - if (project.ext.inFipsJvm) { - systemProperty 'runtime.java', project.ext.runtimeJavaVersion.getMajorVersion() + "FIPS" - } else { - systemProperty 'runtime.java', project.ext.runtimeJavaVersion.getMajorVersion() - } - // TODO: remove setting logging level via system property - systemProperty 'tests.logger.level', 'WARN' - for (Map.Entry property : System.properties.entrySet()) { - if (property.getKey().startsWith('tests.') || - property.getKey().startsWith('es.')) { - if (property.getKey().equals('tests.seed')) { - /* The seed is already set on the project so we - * shouldn't attempt to override it. */ - continue; - } - systemProperty property.getKey(), property.getValue() + doLast { + println "Task $test ended" } - } - // TODO: remove this once ctx isn't added to update script params in 7.0 - systemProperty 'es.scripting.update.ctx_in_params', 'false' + def listener = new ErrorReportingTestListener(test.testLogging) + test.extensions.add(ErrorReportingTestListener, 'errorReportingTestListener', listener) + addTestOutputListener(listener) + addTestListener(listener) - // Set the system keystore/truststore password if we're running tests in a FIPS-140 JVM - if (project.inFipsJvm) { - systemProperty 'javax.net.ssl.trustStorePassword', 'password' - systemProperty 'javax.net.ssl.keyStorePassword', 'password' - } + executable = "${project.runtimeJavaHome}/bin/java" + workingDir = project.file("${project.buildDir}/testrun/${test.name}") + maxParallelForks = project.rootProject.ext.defaultParallel - boolean assertionsEnabled = Boolean.parseBoolean(System.getProperty('tests.asserts', 'true')) - enableSystemAssertions assertionsEnabled - enableAssertions assertionsEnabled + exclude '**/*$*.class' - testLogging { - showNumFailuresAtEnd 25 - slowTests { - heartbeat 10 - summarySize 5 + jvmArgs "-Xmx${System.getProperty('tests.heap.size', '512m')}", + "-Xms${System.getProperty('tests.heap.size', '512m')}", + '-XX:+HeapDumpOnOutOfMemoryError', + "-XX:HeapDumpPath=$heapdumpDir" + + if (project.runtimeJavaVersion >= JavaVersion.VERSION_1_9) { + jvmArgs '--illegal-access=warn' } - stackTraceFilters { - // custom filters: we carefully only omit test infra noise here - contains '.SlaveMain.' - regex(/^(\s+at )(org\.junit\.)/) - // also includes anonymous classes inside these two: - regex(/^(\s+at )(com\.carrotsearch\.randomizedtesting\.RandomizedRunner)/) - regex(/^(\s+at )(com\.carrotsearch\.randomizedtesting\.ThreadLeakControl)/) - regex(/^(\s+at )(com\.carrotsearch\.randomizedtesting\.rules\.)/) - regex(/^(\s+at )(org\.apache\.lucene\.util\.TestRule)/) - regex(/^(\s+at )(org\.apache\.lucene\.util\.AbstractBeforeAfterRule)/) + + if (System.getProperty('tests.jvm.argline')) { + jvmArgs System.getProperty('tests.jvm.argline').split(" ") } - if (System.getProperty('tests.class') != null && System.getProperty('tests.output') == null) { - // if you are debugging, you want to see the output! - outputMode 'always' + + if (Boolean.parseBoolean(System.getProperty('tests.asserts', 'true'))) { + jvmArgs '-ea', '-esa' + } + + // we use './temp' since this is per JVM and tests are forbidden from writing to CWD + systemProperties 'gradle.dist.lib': new File(project.class.location.toURI()).parent, + 'gradle.worker.jar': "${project.gradle.getGradleUserHomeDir()}/caches/${project.gradle.gradleVersion}/workerMain/gradle-worker.jar", + 'gradle.user.home': project.gradle.getGradleUserHomeDir(), + 'java.io.tmpdir': './temp', + 'java.awt.headless': 'true', + 'tests.gradle': 'true', + 'tests.artifact': project.name, + 'tests.task': path, + 'tests.security.manager': 'true', + 'tests.seed': project.testSeed, + 'jna.nosys': 'true', + 'compiler.java': project.ext.compilerJavaVersion.getMajorVersion() + + if (project.ext.inFipsJvm) { + systemProperty 'runtime.java', project.ext.runtimeJavaVersion.getMajorVersion() + "FIPS" } else { - outputMode System.getProperty('tests.output', 'onerror') + systemProperty 'runtime.java', project.ext.runtimeJavaVersion.getMajorVersion() + } + // TODO: remove setting logging level via system property + systemProperty 'tests.logger.level', 'WARN' + System.getProperties().each { key, value -> + if ((key.startsWith('tests.') || key.startsWith('es.'))) { + systemProperty key, value + } } - } - balancers { - executionTime cacheFilename: ".local-${project.version}-${name}-execution-times.log" - } + // TODO: remove this once ctx isn't added to update script params in 7.0 + systemProperty 'es.scripting.update.ctx_in_params', 'false' - listeners { - junitReport() - } + // Set the system keystore/truststore password if we're running tests in a FIPS-140 JVM + if (project.inFipsJvm) { + systemProperty 'javax.net.ssl.trustStorePassword', 'password' + systemProperty 'javax.net.ssl.keyStorePassword', 'password' + } - exclude '**/*$*.class' + testLogging { + showExceptions = true + showCauses = true + exceptionFormat = 'full' + } - project.plugins.withType(ShadowPlugin).whenPluginAdded { - // Test against a shadow jar if we made one - classpath -= project.tasks.compileJava.outputs.files - classpath += project.tasks.shadowJar.outputs.files - dependsOn project.tasks.shadowJar + project.plugins.withType(ShadowPlugin).whenPluginAdded { + // Test against a shadow jar if we made one + classpath -= project.tasks.compileJava.outputs.files + classpath += project.tasks.shadowJar.outputs.files + + dependsOn project.tasks.shadowJar + } } } } - private static String findDefaultParallel(Project project) { + private static int findDefaultParallel(Project project) { if (project.file("/proc/cpuinfo").exists()) { // Count physical cores on any Linux distro ( don't count hyper-threading ) Map socketToCore = [:] @@ -1046,7 +1028,7 @@ class BuildPlugin implements Plugin { } } }) - return socketToCore.values().sum().toString(); + return socketToCore.values().sum() } else if ('Mac OS X'.equals(System.getProperty('os.name'))) { // Ask macOS to count physical CPUs for us ByteArrayOutputStream stdout = new ByteArrayOutputStream() @@ -1055,16 +1037,9 @@ class BuildPlugin implements Plugin { args '-n', 'hw.physicalcpu' standardOutput = stdout } - return stdout.toString('UTF-8').trim(); - } - return 'auto'; - } - - /** Configures the test task */ - static Task configureTest(Project project) { - project.tasks.getByName('test') { - include '**/*Tests.class' + return Integer.parseInt(stdout.toString('UTF-8').trim()) } + return Runtime.getRuntime().availableProcessors() / 2 } private static configurePrecommit(Project project) { @@ -1094,4 +1069,58 @@ class BuildPlugin implements Plugin { deps.mappings = project.dependencyLicenses.mappings } } + + /** + * Pins the test seed at configuration time so it isn't different on every + * {@link Test} execution. This is useful if random + * decisions in one run of {@linkplain Test} influence the + * outcome of subsequent runs. Pinning the seed up front like this makes + * the reproduction line from one run be useful on another run. + */ + static String setupSeed(Project project) { + if (project.rootProject.ext.has('testSeed')) { + /* Skip this if we've already pinned the testSeed. It is important + * that this checks the rootProject so that we know we've only ever + * initialized one time. */ + return project.rootProject.ext.testSeed + } + + String testSeed = System.getProperty('tests.seed') + if (testSeed == null) { + long seed = new Random(System.currentTimeMillis()).nextLong() + testSeed = Long.toUnsignedString(seed, 16).toUpperCase(Locale.ROOT) + } + + project.rootProject.ext.testSeed = testSeed + return testSeed + } + + private static class TestFailureReportingPlugin implements Plugin { + @Override + void apply(Project project) { + if (project != project.rootProject) { + throw new IllegalStateException("${this.class.getName()} can only be applied to the root project.") + } + + project.gradle.addListener(new TaskActionListener() { + @Override + void beforeActions(Task task) { + + } + + @Override + void afterActions(Task task) { + if (task instanceof Test) { + ErrorReportingTestListener listener = task.extensions.findByType(ErrorReportingTestListener) + if (listener != null && listener.getFailedTests().size() > 0) { + task.logger.lifecycle("\nTests with failures:") + listener.getFailedTests().each { + task.logger.lifecycle(" - ${it.getFullName()}") + } + } + } + } + }) + } + } } diff --git a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/LoggingOutputStream.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/LoggingOutputStream.groovy similarity index 97% rename from buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/LoggingOutputStream.groovy rename to buildSrc/src/main/groovy/org/elasticsearch/gradle/LoggingOutputStream.groovy index ce0995a5a8c70..e2e2b7c954482 100644 --- a/buildSrc/src/main/groovy/com/carrotsearch/gradle/junit4/LoggingOutputStream.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/LoggingOutputStream.groovy @@ -1,4 +1,4 @@ -package com.carrotsearch.gradle.junit4 +package org.elasticsearch.gradle import org.gradle.api.logging.LogLevel import org.gradle.api.logging.Logger diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy index 4d9cc38323b13..df26a5a07cb21 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy @@ -18,30 +18,36 @@ */ package org.elasticsearch.gradle.test -import com.carrotsearch.gradle.junit4.RandomizedTestingTask import org.elasticsearch.gradle.VersionProperties import org.elasticsearch.gradle.testclusters.ElasticsearchCluster import org.elasticsearch.gradle.testclusters.TestClustersPlugin import org.gradle.api.DefaultTask import org.gradle.api.Task import org.gradle.api.execution.TaskExecutionAdapter +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging import org.gradle.api.tasks.Copy import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskState import org.gradle.api.tasks.options.Option +import org.gradle.api.tasks.testing.Test import org.gradle.plugins.ide.idea.IdeaPlugin +import org.gradle.process.CommandLineArgumentProvider import java.nio.charset.StandardCharsets import java.nio.file.Files import java.util.stream.Stream + /** * A wrapper task around setting up a cluster and running rest tests. */ -public class RestIntegTestTask extends DefaultTask { +class RestIntegTestTask extends DefaultTask { + + private static final Logger LOGGER = Logging.getLogger(RestIntegTestTask) protected ClusterConfiguration clusterConfig - protected RandomizedTestingTask runner + protected Test runner protected Task clusterInit @@ -52,8 +58,8 @@ public class RestIntegTestTask extends DefaultTask { @Input Boolean includePackaged = false - public RestIntegTestTask() { - runner = project.tasks.create("${name}Runner", RandomizedTestingTask.class) + RestIntegTestTask() { + runner = project.tasks.create("${name}Runner", Test.class) super.dependsOn(runner) clusterInit = project.tasks.create(name: "${name}Cluster#init", dependsOn: project.testClasses) runner.dependsOn(clusterInit) @@ -71,35 +77,66 @@ public class RestIntegTestTask extends DefaultTask { runner.useCluster project.testClusters."$name" } + // disable the build cache for rest test tasks + // there are a number of inputs we aren't properly tracking here so we'll just not cache these for now + runner.outputs.doNotCacheIf('Caching is disabled for REST integration tests') { true } + // override/add more for rest tests - runner.parallelism = '1' + runner.maxParallelForks = 1 runner.include('**/*IT.class') runner.systemProperty('tests.rest.load_packaged', 'false') + /* + * We use lazy-evaluated strings in order to configure system properties whose value will not be known until + * execution time (e.g. cluster port numbers). Adding these via the normal DSL doesn't work as these get treated + * as task inputs and therefore Gradle attempts to snapshot them before/after task execution. This fails due + * to the GStrings containing references to non-serializable objects. + * + * We bypass this by instead passing this system properties vi a CommandLineArgumentProvider. This has the added + * side-effect that these properties are NOT treated as inputs, therefore they don't influence things like the + * build cache key or up to date checking. + */ + def nonInputProperties = new CommandLineArgumentProvider() { + private final Map systemProperties = [:] + + void systemProperty(String key, Object value) { + systemProperties.put(key, value) + } + + @Override + Iterable asArguments() { + return systemProperties.collect { key, value -> + "-D${key}=${value.toString()}".toString() + } + } + } + runner.jvmArgumentProviders.add(nonInputProperties) + runner.ext.nonInputProperties = nonInputProperties + if (System.getProperty("tests.rest.cluster") == null) { if (System.getProperty("tests.cluster") != null) { throw new IllegalArgumentException("tests.rest.cluster and tests.cluster must both be null or non-null") } if (usesTestclusters == true) { ElasticsearchCluster cluster = project.testClusters."${name}" - runner.systemProperty('tests.rest.cluster', {cluster.allHttpSocketURI.join(",") }) - runner.systemProperty('tests.config.dir', {cluster.singleNode().getConfigDir()}) - runner.systemProperty('tests.cluster', {cluster.transportPortURI}) + nonInputProperties.systemProperty('tests.rest.cluster', "${-> cluster.allHttpSocketURI.join(",") }") + nonInputProperties.systemProperty('tests.config.dir', "${-> cluster.singleNode().getConfigDir() }") + nonInputProperties.systemProperty('tests.cluster', "${-> cluster.transportPortURI }") } else { // we pass all nodes to the rest cluster to allow the clients to round-robin between them // this is more realistic than just talking to a single node - runner.systemProperty('tests.rest.cluster', "${-> nodes.collect { it.httpUri() }.join(",")}") - runner.systemProperty('tests.config.dir', "${-> nodes[0].pathConf}") + nonInputProperties.systemProperty('tests.rest.cluster', "${-> nodes.collect { it.httpUri() }.join(",")}") + nonInputProperties.systemProperty('tests.config.dir', "${-> nodes[0].pathConf}") // TODO: our "client" qa tests currently use the rest-test plugin. instead they should have their own plugin // that sets up the test cluster and passes this transport uri instead of http uri. Until then, we pass // both as separate sysprops - runner.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}") + nonInputProperties.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}") // dump errors and warnings from cluster log on failure TaskExecutionAdapter logDumpListener = new TaskExecutionAdapter() { @Override void afterExecute(Task task, TaskState state) { - if (state.failure != null) { + if (task == runner && state.failure != null) { for (NodeInfo nodeInfo : nodes) { printLogExcerpt(nodeInfo) } @@ -194,9 +231,9 @@ public class RestIntegTestTask extends DefaultTask { /** Print out an excerpt of the log from the given node. */ protected static void printLogExcerpt(NodeInfo nodeInfo) { File logFile = new File(nodeInfo.homeDir, "logs/${nodeInfo.clusterName}.log") - println("\nCluster ${nodeInfo.clusterName} - node ${nodeInfo.nodeNum} log excerpt:") - println("(full log at ${logFile})") - println('-----------------------------------------') + LOGGER.lifecycle("\nCluster ${nodeInfo.clusterName} - node ${nodeInfo.nodeNum} log excerpt:") + LOGGER.lifecycle("(full log at ${logFile})") + LOGGER.lifecycle('-----------------------------------------') Stream stream = Files.lines(logFile.toPath(), StandardCharsets.UTF_8) try { boolean inStartup = true @@ -211,9 +248,9 @@ public class RestIntegTestTask extends DefaultTask { } if (inStartup || inExcerpt) { if (linesSkipped != 0) { - println("... SKIPPED ${linesSkipped} LINES ...") + LOGGER.lifecycle("... SKIPPED ${linesSkipped} LINES ...") } - println(line) + LOGGER.lifecycle(line) linesSkipped = 0 } else { ++linesSkipped @@ -225,7 +262,7 @@ public class RestIntegTestTask extends DefaultTask { } finally { stream.close() } - println('=========================================') + LOGGER.lifecycle('=========================================') } diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy index 9e41466ebdd73..2a858206ebd72 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy @@ -20,7 +20,8 @@ package org.elasticsearch.gradle.test -import com.carrotsearch.gradle.junit4.RandomizedTestingPlugin + +import groovy.transform.CompileStatic import org.elasticsearch.gradle.BuildPlugin import org.elasticsearch.gradle.ExportElasticsearchBuildResourcesTask import org.elasticsearch.gradle.VersionProperties @@ -28,48 +29,66 @@ import org.elasticsearch.gradle.precommit.PrecommitTasks import org.gradle.api.InvalidUserDataException import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.api.tasks.testing.Test +import org.gradle.plugins.ide.eclipse.model.EclipseModel +import org.gradle.plugins.ide.idea.model.IdeaModel + /** * Configures the build to compile tests against Elasticsearch's test framework * and run REST tests. Use BuildPlugin if you want to build main code as well * as tests. */ -public class StandaloneRestTestPlugin implements Plugin { +@CompileStatic +class StandaloneRestTestPlugin implements Plugin { @Override - public void apply(Project project) { + void apply(Project project) { if (project.pluginManager.hasPlugin('elasticsearch.build')) { throw new InvalidUserDataException('elasticsearch.standalone-test ' + 'elasticsearch.standalone-rest-test, and elasticsearch.build ' + 'are mutually exclusive') } project.pluginManager.apply(JavaBasePlugin) - project.pluginManager.apply(RandomizedTestingPlugin) project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask) BuildPlugin.globalBuildInfo(project) BuildPlugin.configureRepositories(project) - BuildPlugin.applyCommonTestConfig(project) + BuildPlugin.configureTestTasks(project) // only setup tests to build - project.sourceSets.create('test') + SourceSetContainer sourceSets = project.extensions.getByType(SourceSetContainer) + SourceSet testSourceSet = sourceSets.create('test') + + project.tasks.withType(Test) { Test test -> + test.testClassesDirs = testSourceSet.output.classesDirs + test.classpath = testSourceSet.runtimeClasspath + } + // create a compileOnly configuration as others might expect it project.configurations.create("compileOnly") project.dependencies.add('testCompile', "org.elasticsearch.test:framework:${VersionProperties.elasticsearch}") - project.eclipse.classpath.sourceSets = [project.sourceSets.test] - project.eclipse.classpath.plusConfigurations = [project.configurations.testRuntime] - project.idea.module.testSourceDirs += project.sourceSets.test.java.srcDirs - project.idea.module.scopes['TEST'] = [plus: [project.configurations.testRuntime]] + EclipseModel eclipse = project.extensions.getByType(EclipseModel) + eclipse.classpath.sourceSets = [testSourceSet] + eclipse.classpath.plusConfigurations = [project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME)] + + IdeaModel idea = project.extensions.getByType(IdeaModel) + idea.module.testSourceDirs += testSourceSet.java.srcDirs + idea.module.scopes.put('TEST', [plus: [project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME)]] as Map>) PrecommitTasks.create(project, false) - project.check.dependsOn(project.precommit) + project.tasks.getByName('check').dependsOn(project.tasks.getByName('precommit')) - project.tasks.withType(JavaCompile) { + project.tasks.withType(JavaCompile) { JavaCompile task -> // This will be the default in Gradle 5.0 - if (options.compilerArgs.contains("-processor") == false) { - options.compilerArgs << '-proc:none' + if (task.options.compilerArgs.contains("-processor") == false) { + task.options.compilerArgs << '-proc:none' } } } diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneTestPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneTestPlugin.groovy index 95818240cdaaa..ccdffd6458aa4 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneTestPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneTestPlugin.groovy @@ -19,34 +19,30 @@ package org.elasticsearch.gradle.test -import com.carrotsearch.gradle.junit4.RandomizedTestingTask +import groovy.transform.CompileStatic import org.elasticsearch.gradle.BuildPlugin import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.tasks.testing.Test /** * Configures the build to compile against Elasticsearch's test framework and * run integration and unit tests. Use BuildPlugin if you want to build main * code as well as tests. */ -public class StandaloneTestPlugin implements Plugin { +@CompileStatic +class StandaloneTestPlugin implements Plugin { @Override - public void apply(Project project) { + void apply(Project project) { project.pluginManager.apply(StandaloneRestTestPlugin) - Map testOptions = [ - name: 'test', - type: RandomizedTestingTask, - dependsOn: 'testClasses', - group: JavaBasePlugin.VERIFICATION_GROUP, - description: 'Runs unit tests that are separate' - ] - RandomizedTestingTask test = project.tasks.create(testOptions) + Test test = project.tasks.create('test', Test) + test.group = JavaBasePlugin.VERIFICATION_GROUP + test.description = 'Runs unit tests that are separate' + BuildPlugin.configureCompile(project) - test.classpath = project.sourceSets.test.runtimeClasspath - test.testClassesDirs = project.sourceSets.test.output.classesDirs - test.mustRunAfter(project.precommit) - project.check.dependsOn(test) + test.mustRunAfter(project.tasks.getByName('precommit')) + project.tasks.getByName('check').dependsOn(test) } } diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy index e15759a1fe588..0be294fb00523 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/TapLoggerOutputStream.groovy @@ -18,7 +18,7 @@ */ package org.elasticsearch.gradle.vagrant -import com.carrotsearch.gradle.junit4.LoggingOutputStream +import org.elasticsearch.gradle.LoggingOutputStream import org.gradle.api.GradleScriptException import org.gradle.api.logging.Logger import org.gradle.internal.logging.progress.ProgressLogger diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy index e899c0171298b..f3031f73c236d 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantLoggerOutputStream.groovy @@ -18,7 +18,7 @@ */ package org.elasticsearch.gradle.vagrant -import com.carrotsearch.gradle.junit4.LoggingOutputStream +import org.elasticsearch.gradle.LoggingOutputStream import org.gradle.internal.logging.progress.ProgressLogger /** diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/TestingConventionsTasks.java b/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/TestingConventionsTasks.java index 04e1343f4ac92..b2228f5c1b132 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/TestingConventionsTasks.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/TestingConventionsTasks.java @@ -31,12 +31,10 @@ import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.testing.Test; -import org.gradle.api.tasks.util.PatternFilterable; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; @@ -75,17 +73,6 @@ public TestingConventionsTasks() { public Map> classFilesPerEnabledTask(FileTree testClassFiles) { Map> collector = new HashMap<>(); - // RandomizedTestingTask - collector.putAll( - getProject().getTasks().withType(getRandomizedTestingTask()).stream() - .filter(Task::getEnabled) - .collect(Collectors.toMap( - Task::getPath, - task -> testClassFiles.matching(getRandomizedTestingPatternSet(task)).getFiles() - ) - ) - ); - // Gradle Test collector.putAll( getProject().getTasks().withType(Test.class).stream() @@ -279,32 +266,6 @@ private String collectProblems(String... problems) { .collect(Collectors.joining("\n")); } - @SuppressWarnings("unchecked") - private PatternFilterable getRandomizedTestingPatternSet(Task task) { - try { - if ( - getRandomizedTestingTask().isAssignableFrom(task.getClass()) == false - ) { - throw new IllegalStateException("Expected " + task + " to be RandomizedTestingTask or Test but it was " + task.getClass()); - } - Method getPatternSet = task.getClass().getMethod("getPatternSet"); - return (PatternFilterable) getPatternSet.invoke(task); - } catch (NoSuchMethodException e) { - throw new IllegalStateException("Expecte task to have a `patternSet` " + task, e); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Failed to get pattern set from task" + task, e); - } - } - - @SuppressWarnings("unchecked") - private Class getRandomizedTestingTask() { - try { - return (Class) Class.forName("com.carrotsearch.gradle.junit4.RandomizedTestingTask"); - } catch (ClassNotFoundException | ClassCastException e) { - throw new IllegalStateException("Failed to load randomized testing class", e); - } - } - private String checkNoneExists(String message, Stream> stream) { String problem = stream .map(each -> " * " + each.getName()) diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/test/ErrorReportingTestListener.java b/buildSrc/src/main/java/org/elasticsearch/gradle/test/ErrorReportingTestListener.java new file mode 100644 index 0000000000000..397adf3ec946c --- /dev/null +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/test/ErrorReportingTestListener.java @@ -0,0 +1,180 @@ +package org.elasticsearch.gradle.test; + +import org.gradle.api.internal.tasks.testing.logging.FullExceptionFormatter; +import org.gradle.api.internal.tasks.testing.logging.TestExceptionFormatter; +import org.gradle.api.tasks.testing.TestDescriptor; +import org.gradle.api.tasks.testing.TestListener; +import org.gradle.api.tasks.testing.TestOutputEvent; +import org.gradle.api.tasks.testing.TestOutputListener; +import org.gradle.api.tasks.testing.TestResult; +import org.gradle.api.tasks.testing.logging.TestLogging; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class ErrorReportingTestListener implements TestOutputListener, TestListener { + private static final String REPRODUCE_WITH_PREFIX = "REPRODUCE WITH"; + + private final TestExceptionFormatter formatter; + private Map> eventBuffer = new ConcurrentHashMap<>(); + private Set failedTests = new LinkedHashSet<>(); + + public ErrorReportingTestListener(TestLogging testLogging) { + this.formatter = new FullExceptionFormatter(testLogging); + } + + @Override + public void onOutput(TestDescriptor testDescriptor, TestOutputEvent outputEvent) { + TestDescriptor suite = testDescriptor.getParent(); + + // Check if this is output from the test suite itself (e.g. afterTest or beforeTest) + if (testDescriptor.isComposite()) { + suite = testDescriptor; + } + + List events = eventBuffer.computeIfAbsent(Descriptor.of(suite), d -> new ArrayList<>()); + events.add(outputEvent); + } + + @Override + public void beforeSuite(TestDescriptor suite) { + + } + + @Override + public void afterSuite(final TestDescriptor suite, TestResult result) { + try { + // if the test suite failed, report all captured output + if (result.getResultType().equals(TestResult.ResultType.FAILURE)) { + List events = eventBuffer.get(Descriptor.of(suite)); + + if (events != null) { + // It's not explicit what the threading guarantees are for TestListener method execution so we'll + // be explicitly safe here to avoid interleaving output from multiple test suites + synchronized (this) { + System.err.println("\n\nSuite: " + suite); + + for (TestOutputEvent event : events) { + log(event.getMessage(), event.getDestination()); + } + } + } + } + } finally { + // make sure we don't hold on to test output in memory after the suite has finished + eventBuffer.remove(Descriptor.of(suite)); + } + } + + @Override + public void beforeTest(TestDescriptor testDescriptor) { + + } + + @Override + public void afterTest(TestDescriptor testDescriptor, TestResult result) { + if (result.getResultType() == TestResult.ResultType.FAILURE) { + failedTests.add(Descriptor.of(testDescriptor)); + + if (testDescriptor.getParent() != null) { + // go back and find the reproduction line for this test failure + List events = eventBuffer.get(Descriptor.of(testDescriptor.getParent())); + for (int i = events.size() - 1; i >= 0; i--) { + String message = events.get(i).getMessage(); + if (message.startsWith(REPRODUCE_WITH_PREFIX)) { + System.err.print('\n' + message); + break; + } + } + + // include test failure exception stacktraces in test suite output log + if (result.getExceptions().size() > 0) { + String message = formatter.format(testDescriptor, result.getExceptions()).substring(4); + + events.add(new TestOutputEvent() { + @Override + public Destination getDestination() { + return Destination.StdErr; + } + + @Override + public String getMessage() { + return message; + } + }); + } + } + } + } + + public Set getFailedTests() { + return failedTests; + } + + private static void log(String message, TestOutputEvent.Destination destination) { + PrintStream out; + String prefix; + + if (destination == TestOutputEvent.Destination.StdOut) { + out = System.out; + prefix = " 1> "; + } else { + out = System.err; + prefix = " 2> "; + } + + if (message.equals("\n")) { + out.print(message); + } else { + out.print(prefix); + out.print(message); + } + } + + /** + * Class for identifying test output sources. We use this rather than Gradle's {@link TestDescriptor} as we want + * to avoid any nasty memory leak issues that come from keeping Gradle implementation types in memory. Since we + * use this a the key for our HashMap, it's best to control the implementation as there's no guarantee that Gradle's + * various {@link TestDescriptor} implementations reliably implement equals and hashCode. + */ + public static class Descriptor { + private final String name; + private final String className; + private final String parent; + + private Descriptor(String name, String className, String parent) { + this.name = name; + this.className = className; + this.parent = parent; + } + + public static Descriptor of(TestDescriptor d) { + return new Descriptor(d.getName(), d.getClassName(), d.getParent() == null ? null : d.getParent().toString()); + } + + public String getFullName() { + return className + "." + name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Descriptor that = (Descriptor) o; + return Objects.equals(name, that.name) && + Objects.equals(className, that.className) && + Objects.equals(parent, that.parent); + } + + @Override + public int hashCode() { + return Objects.hash(name, className, parent); + } + } +} diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/testfixtures/TestFixturesPlugin.java b/buildSrc/src/main/java/org/elasticsearch/gradle/testfixtures/TestFixturesPlugin.java index 3d64578e0147b..b930955236fb8 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/testfixtures/TestFixturesPlugin.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/testfixtures/TestFixturesPlugin.java @@ -32,9 +32,8 @@ import org.gradle.api.plugins.BasePlugin; import org.gradle.api.plugins.ExtraPropertiesExtension; import org.gradle.api.tasks.TaskContainer; +import org.gradle.api.tasks.testing.Test; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Collections; import java.util.function.BiConsumer; @@ -103,7 +102,7 @@ public void apply(Project project) { .matching(fixtureProject -> fixtureProject.equals(project) == false) .all(fixtureProject -> project.evaluationDependsOn(fixtureProject.getPath())); - conditionTaskByType(tasks, extension, getTaskClass("com.carrotsearch.gradle.junit4.RandomizedTestingTask")); + conditionTaskByType(tasks, extension, Test.class); conditionTaskByType(tasks, extension, getTaskClass("org.elasticsearch.gradle.test.RestIntegTestTask")); conditionTaskByType(tasks, extension, TestingConventionsTasks.class); conditionTaskByType(tasks, extension, ComposeUp.class); @@ -116,18 +115,14 @@ public void apply(Project project) { return; } - tasks.withType(getTaskClass("com.carrotsearch.gradle.junit4.RandomizedTestingTask"), task -> + tasks.withType(Test.class, task -> extension.fixtures.all(fixtureProject -> { - fixtureProject.getTasks().matching(it -> it.getName().equals("buildFixture")).all(buildFixture -> - task.dependsOn(buildFixture) - ); - fixtureProject.getTasks().matching(it -> it.getName().equals("composeDown")).all(composeDown -> - task.finalizedBy(composeDown) - ); + fixtureProject.getTasks().matching(it -> it.getName().equals("buildFixture")).all(task::dependsOn); + fixtureProject.getTasks().matching(it -> it.getName().equals("composeDown")).all(task::finalizedBy); configureServiceInfoForTask( task, fixtureProject, - (name, port) -> setSystemProperty(task, name, port) + task::systemProperty ); task.dependsOn(fixtureProject.getTasks().getByName("postProcessFixture")); }) @@ -182,17 +177,6 @@ public boolean dockerComposeSupported(Project project) { return hasDockerCompose && Boolean.parseBoolean(System.getProperty("tests.fixture.enabled", "true")); } - private void setSystemProperty(Task task, String name, Object value) { - try { - Method systemProperty = task.getClass().getMethod("systemProperty", String.class, Object.class); - systemProperty.invoke(task, name, value); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException("Could not find systemProperty method on RandomizedTestingTask", e); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalArgumentException("Could not call systemProperty method on RandomizedTestingTask", e); - } - } - private void disableTaskByType(TaskContainer tasks, Class type) { tasks.withType(type, task -> task.setEnabled(false)); } diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/carrotsearch.randomized-testing.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/carrotsearch.randomized-testing.properties deleted file mode 100644 index e1a1b8297c8eb..0000000000000 --- a/buildSrc/src/main/resources/META-INF/gradle-plugins/carrotsearch.randomized-testing.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=com.carrotsearch.gradle.junit4.RandomizedTestingPlugin diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/TestingConventionsTasksIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/TestingConventionsTasksIT.java index 39ab8a6734c58..c6e1e2783cebc 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/TestingConventionsTasksIT.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/TestingConventionsTasksIT.java @@ -62,7 +62,7 @@ public void testNoEmptyTasks() { BuildResult result = runner.buildAndFail(); assertOutputContains(result.getOutput(), "Expected at least one test class included in task :empty_test_task:emptyTest, but found none.", - "Expected at least one test class included in task :empty_test_task:emptyTestRandomized, but found none." + "Expected at least one test class included in task :empty_test_task:test, but found none." ); } @@ -71,9 +71,8 @@ public void testAllTestTasksIncluded() { .withArguments("clean", ":all_classes_in_tasks:testingConventions", "-i", "-s"); BuildResult result = runner.buildAndFail(); assertOutputContains(result.getOutput(), - "Test classes are not included in any enabled task (:all_classes_in_tasks:emptyTestRandomized):", - " * org.elasticsearch.gradle.testkit.NamingConventionIT", - " * org.elasticsearch.gradle.testkit.NamingConventionTests" + "Test classes are not included in any enabled task (:all_classes_in_tasks:test):", + " * org.elasticsearch.gradle.testkit.NamingConventionIT" ); } diff --git a/buildSrc/src/testKit/elasticsearch.build/build.gradle b/buildSrc/src/testKit/elasticsearch.build/build.gradle index 409367da3146a..8020935f67e80 100644 --- a/buildSrc/src/testKit/elasticsearch.build/build.gradle +++ b/buildSrc/src/testKit/elasticsearch.build/build.gradle @@ -27,7 +27,7 @@ forbiddenApisTest.enabled = false // requires dependency on testing fw jarHell.enabled = false // we don't have tests for now -unitTest.enabled = false +test.enabled = false task hello { doFirst { diff --git a/buildSrc/src/testKit/testingConventions/build.gradle b/buildSrc/src/testKit/testingConventions/build.gradle index 0052245099112..dd82a18085fa1 100644 --- a/buildSrc/src/testKit/testingConventions/build.gradle +++ b/buildSrc/src/testKit/testingConventions/build.gradle @@ -25,22 +25,16 @@ allprojects { baseClasses = [] } } - - unitTest.enabled = false } project(':empty_test_task') { task emptyTest(type: Test) { } - - task emptyTestRandomized(type: com.carrotsearch.gradle.junit4.RandomizedTestingTask) { - - } } project(':all_classes_in_tasks') { - task emptyTestRandomized(type: com.carrotsearch.gradle.junit4.RandomizedTestingTask) { + test { include "**/Convention*" } } @@ -54,14 +48,14 @@ project(':not_implementing_base') { baseClass 'org.elasticsearch.gradle.testkit.Integration' } } - task randomized(type: com.carrotsearch.gradle.junit4.RandomizedTestingTask) { + test { include "**/*IT.class" include "**/*Tests.class" } } project(':valid_setup_no_base') { - task randomized(type: com.carrotsearch.gradle.junit4.RandomizedTestingTask) { + test { include "**/*IT.class" include "**/*Tests.class" } @@ -72,7 +66,7 @@ project(':tests_in_main') { } project (':valid_setup_with_base') { - task randomized(type: com.carrotsearch.gradle.junit4.RandomizedTestingTask) { + test { include "**/*IT.class" include "**/*Tests.class" } diff --git a/client/benchmark/build.gradle b/client/benchmark/build.gradle index f8beeafd14e09..a53f102034009 100644 --- a/client/benchmark/build.gradle +++ b/client/benchmark/build.gradle @@ -29,7 +29,7 @@ archivesBaseName = 'client-benchmarks' mainClassName = 'org.elasticsearch.client.benchmark.BenchmarkMain' // never try to invoke tests on the benchmark project - there aren't any -unitTest.enabled = false +test.enabled = false dependencies { compile 'org.apache.commons:commons-math3:3.2' diff --git a/client/client-benchmark-noop-api-plugin/build.gradle b/client/client-benchmark-noop-api-plugin/build.gradle index 6df52237e367e..b5a5fb5dc5ed1 100644 --- a/client/client-benchmark-noop-api-plugin/build.gradle +++ b/client/client-benchmark-noop-api-plugin/build.gradle @@ -36,5 +36,5 @@ dependenciesInfo.enabled = false compileJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-try,-unchecked" // no unit tests -unitTest.enabled = false +test.enabled = false integTest.enabled = false diff --git a/client/test/build.gradle b/client/test/build.gradle index 25cf23672dac6..faf5fb7bddf46 100644 --- a/client/test/build.gradle +++ b/client/test/build.gradle @@ -53,4 +53,4 @@ dependenciesInfo.enabled = false //we aren't releasing this jar thirdPartyAudit.enabled = false -unitTest.enabled = false +test.enabled = false diff --git a/distribution/archives/integ-test-zip/build.gradle b/distribution/archives/integ-test-zip/build.gradle index d79971907b50d..f44136b2565cc 100644 --- a/distribution/archives/integ-test-zip/build.gradle +++ b/distribution/archives/integ-test-zip/build.gradle @@ -26,7 +26,7 @@ integTestRunner { * when running against an external cluster. */ if (System.getProperty("tests.rest.cluster") == null) { - systemProperty 'tests.logfile', + nonInputProperties.systemProperty 'tests.logfile', "${ -> integTest.nodes[0].homeDir}/logs/${ -> integTest.nodes[0].clusterName }_server.json" } else { systemProperty 'tests.logfile', '--external--' diff --git a/distribution/tools/java-version-checker/build.gradle b/distribution/tools/java-version-checker/build.gradle index 03ac32d20b7d6..c8fe9e1121953 100644 --- a/distribution/tools/java-version-checker/build.gradle +++ b/distribution/tools/java-version-checker/build.gradle @@ -7,7 +7,7 @@ forbiddenApisMain { replaceSignatureFiles 'jdk-signatures' } -unitTest.enabled = false +test.enabled = false javadoc.enabled = false loggerUsageCheck.enabled = false jarHell.enabled = false diff --git a/distribution/tools/plugin-cli/build.gradle b/distribution/tools/plugin-cli/build.gradle index b5acb105407d6..61e3546ed8919 100644 --- a/distribution/tools/plugin-cli/build.gradle +++ b/distribution/tools/plugin-cli/build.gradle @@ -35,7 +35,7 @@ dependencyLicenses { mapping from: /bc.*/, to: 'bouncycastle' } -unitTest { +test { // TODO: find a way to add permissions for the tests in this module systemProperty 'tests.security.manager', 'false' } diff --git a/libs/cli/build.gradle b/libs/cli/build.gradle index 0cd1f256c4037..b1f3b338255c4 100644 --- a/libs/cli/build.gradle +++ b/libs/cli/build.gradle @@ -26,7 +26,7 @@ dependencies { compile "org.elasticsearch:elasticsearch-core:${version}" } -unitTest.enabled = false +test.enabled = false // Since CLI does not depend on :server, it cannot run the jarHell task jarHell.enabled = false diff --git a/libs/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java b/libs/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java index 3de0ae5117e6a..277698bd8cc7f 100644 --- a/libs/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java +++ b/libs/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java @@ -196,18 +196,23 @@ public static void checkJarHell(Set urls, Consumer output) throws U // case for tests: where we have class files in the classpath final Path root = PathUtils.get(url.toURI()); final String sep = root.getFileSystem().getSeparator(); - Files.walkFileTree(root, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String entry = root.relativize(file).toString(); - if (entry.endsWith(".class")) { - // normalize with the os separator, remove '.class' - entry = entry.replace(sep, ".").substring(0, entry.length() - ".class".length()); - checkClass(clazzes, entry, path); + + // don't try and walk class or resource directories that don't exist + // gradle will add these to the classpath even if they never get created + if (Files.exists(root)) { + Files.walkFileTree(root, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String entry = root.relativize(file).toString(); + if (entry.endsWith(".class")) { + // normalize with the os separator, remove '.class' + entry = entry.replace(sep, ".").substring(0, entry.length() - ".class".length()); + checkClass(clazzes, entry, path); + } + return super.visitFile(file, attrs); } - return super.visitFile(file, attrs); - } - }); + }); + } } } } diff --git a/libs/plugin-classloader/build.gradle b/libs/plugin-classloader/build.gradle index 4b3e00467b71d..d6af6600d3463 100644 --- a/libs/plugin-classloader/build.gradle +++ b/libs/plugin-classloader/build.gradle @@ -17,7 +17,7 @@ * under the License. */ -unitTest.enabled = false +test.enabled = false // test depend on ES core... forbiddenApisMain.enabled = false diff --git a/modules/lang-painless/build.gradle b/modules/lang-painless/build.gradle index 9260f871e47f5..a8733fef90d56 100644 --- a/modules/lang-painless/build.gradle +++ b/modules/lang-painless/build.gradle @@ -37,8 +37,8 @@ dependencyLicenses { mapping from: /asm-.*/, to: 'asm' } -unitTest { - jvmArg '-XX:-OmitStackTraceInFastThrow' +test { + jvmArgs '-XX:-OmitStackTraceInFastThrow' } /* Build Javadoc for the Java classes in Painless's public API that are in the diff --git a/modules/lang-painless/spi/build.gradle b/modules/lang-painless/spi/build.gradle index 92fd70411f74c..7e43a242a23a9 100644 --- a/modules/lang-painless/spi/build.gradle +++ b/modules/lang-painless/spi/build.gradle @@ -37,4 +37,4 @@ dependencies { } // no tests...yet? -unitTest.enabled = false +test.enabled = false diff --git a/modules/reindex/build.gradle b/modules/reindex/build.gradle index 31fbc3ca1f64e..da184deedaa11 100644 --- a/modules/reindex/build.gradle +++ b/modules/reindex/build.gradle @@ -45,7 +45,7 @@ run { setting 'reindex.remote.whitelist', '127.0.0.1:*' } -unitTest { +test { /* * We have to disable setting the number of available processors as tests in the * same JVM randomize processors and will step on each other if we allow them to @@ -143,8 +143,8 @@ if (Os.isFamily(Os.FAMILY_WINDOWS)) { systemProperty "tests.fromOld", "true" /* Use a closure on the string to delay evaluation until right before we * run the integration tests so that we can be sure that the file is - * ready. */ - systemProperty "es${version}.port", "${ -> fixture.addressAndPort }" + * ready. */ + nonInputProperties.systemProperty "es${version}.port", "${ -> fixture.addressAndPort }" } } } diff --git a/modules/transport-netty4/build.gradle b/modules/transport-netty4/build.gradle index 787a4b6e9ecff..e08bba94d57e6 100644 --- a/modules/transport-netty4/build.gradle +++ b/modules/transport-netty4/build.gradle @@ -47,7 +47,7 @@ dependencyLicenses { mapping from: /netty-.*/, to: 'netty' } -unitTest { +test { /* * We have to disable setting the number of available processors as tests in the same JVM randomize processors and will step on each * other if we allow them to set the number of available processors as it's set-once in Netty. diff --git a/plugins/discovery-ec2/build.gradle b/plugins/discovery-ec2/build.gradle index f154c3d7189a0..107d1ecdde363 100644 --- a/plugins/discovery-ec2/build.gradle +++ b/plugins/discovery-ec2/build.gradle @@ -64,7 +64,7 @@ task writeTestJavaPolicy { } } -unitTest { +test { dependsOn writeTestJavaPolicy // this is needed for insecure plugins, remove if possible! systemProperty 'tests.artifact', project.name diff --git a/plugins/discovery-gce/build.gradle b/plugins/discovery-gce/build.gradle index 11d4a7e25fe46..697cc3780a1fd 100644 --- a/plugins/discovery-gce/build.gradle +++ b/plugins/discovery-gce/build.gradle @@ -29,7 +29,7 @@ check { dependsOn 'qa:gce:check' } -unitTest { +test { // this is needed for insecure plugins, remove if possible! systemProperty 'tests.artifact', project.name } diff --git a/plugins/examples/custom-suggester/build.gradle b/plugins/examples/custom-suggester/build.gradle index 7c0d694e1b5ff..977e467391d8b 100644 --- a/plugins/examples/custom-suggester/build.gradle +++ b/plugins/examples/custom-suggester/build.gradle @@ -32,4 +32,4 @@ integTestCluster { } // this plugin has no unit tests, only rest tests -tasks.unitTest.enabled = false +tasks.test.enabled = false diff --git a/plugins/examples/painless-whitelist/build.gradle b/plugins/examples/painless-whitelist/build.gradle index d68a9ee397645..95928c472ca0d 100644 --- a/plugins/examples/painless-whitelist/build.gradle +++ b/plugins/examples/painless-whitelist/build.gradle @@ -35,4 +35,4 @@ if (System.getProperty('tests.distribution') == null) { integTestCluster.distribution = 'oss' } -unitTest.enabled = false +test.enabled = false diff --git a/plugins/examples/rest-handler/build.gradle b/plugins/examples/rest-handler/build.gradle index 025e570bedea4..98dd093ac17a3 100644 --- a/plugins/examples/rest-handler/build.gradle +++ b/plugins/examples/rest-handler/build.gradle @@ -27,7 +27,7 @@ esplugin { } // No unit tests in this example -unitTest.enabled = false +test.enabled = false task exampleFixture(type: org.elasticsearch.gradle.test.AntFixture) { dependsOn testClasses @@ -40,7 +40,7 @@ integTestCluster { dependsOn exampleFixture } integTestRunner { - systemProperty 'external.address', "${ -> exampleFixture.addressAndPort }" + nonInputProperties.systemProperty 'external.address', "${ -> exampleFixture.addressAndPort }" } testingConventions.naming { diff --git a/plugins/examples/script-expert-scoring/build.gradle b/plugins/examples/script-expert-scoring/build.gradle index b054ab47a3198..e9da62acdcff4 100644 --- a/plugins/examples/script-expert-scoring/build.gradle +++ b/plugins/examples/script-expert-scoring/build.gradle @@ -26,5 +26,5 @@ esplugin { noticeFile rootProject.file('NOTICE.txt') } -unitTest.enabled = false +test.enabled = false diff --git a/plugins/repository-hdfs/build.gradle b/plugins/repository-hdfs/build.gradle index d5addc663ca5b..24b03621eba9a 100644 --- a/plugins/repository-hdfs/build.gradle +++ b/plugins/repository-hdfs/build.gradle @@ -24,6 +24,7 @@ import org.elasticsearch.gradle.test.RestIntegTestTask import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths + apply plugin: 'elasticsearch.test.fixtures' esplugin { @@ -150,9 +151,9 @@ project.afterEvaluate { Task restIntegTestTaskRunner = project.tasks.getByName("${integTestTaskName}Runner") restIntegTestTaskRunner.systemProperty "test.krb5.principal.es", "elasticsearch@${realm}" restIntegTestTaskRunner.systemProperty "test.krb5.principal.hdfs", "hdfs/hdfs.build.elastic.co@${realm}" - restIntegTestTaskRunner.jvmArg "-Djava.security.krb5.conf=${krb5conf}" + restIntegTestTaskRunner.jvmArgs "-Djava.security.krb5.conf=${krb5conf}" if (project.runtimeJavaVersion == JavaVersion.VERSION_1_9) { - restIntegTestTaskRunner.jvmArg '--add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED' + restIntegTestTaskRunner.jvmArgs '--add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED' } restIntegTestTaskRunner.systemProperty ( "test.krb5.keytab.hdfs", @@ -221,7 +222,7 @@ if (fixtureSupported) { integTestRunner.systemProperty 'tests.rest.suite', 'hdfs_repository' // Only include the HA integration tests for the HA test task - integTestHaRunner.patternSet.setIncludes(['**/Ha*TestSuiteIT.class']) + integTestHaRunner.setIncludes(['**/Ha*TestSuiteIT.class']) } else { if (legalPath) { logger.warn("hdfsFixture unsupported, please set HADOOP_HOME and put HADOOP_HOME\\bin in PATH") @@ -252,7 +253,7 @@ integTestSecureRunner.systemProperty 'tests.rest.suite', 'secure_hdfs_repository // Ignore HA integration Tests. They are included below as part of integTestSecureHa test runner. integTestSecureRunner.exclude('**/Ha*TestSuiteIT.class') // Only include the HA integration tests for the HA test task -integTestSecureHaRunner.patternSet.setIncludes(['**/Ha*TestSuiteIT.class']) +integTestSecureHaRunner.setIncludes(['**/Ha*TestSuiteIT.class']) thirdPartyAudit { ignoreMissingClasses() diff --git a/plugins/repository-s3/build.gradle b/plugins/repository-s3/build.gradle index 8a2edeb78c507..d933bcef4908c 100644 --- a/plugins/repository-s3/build.gradle +++ b/plugins/repository-s3/build.gradle @@ -2,7 +2,6 @@ import org.elasticsearch.gradle.BuildPlugin import org.elasticsearch.gradle.MavenFilteringHack import org.elasticsearch.gradle.test.AntFixture import org.elasticsearch.gradle.test.RestIntegTestTask -import com.carrotsearch.gradle.junit4.RandomizedTestingTask /* * Licensed to Elasticsearch under one or more contributor @@ -65,14 +64,14 @@ bundlePlugin { } } -task testRepositoryCreds(type: RandomizedTestingTask) { +task testRepositoryCreds(type: Test) { include '**/RepositoryCredentialsTests.class' include '**/S3BlobStoreRepositoryTests.class' systemProperty 'es.allow_insecure_settings', 'true' } check.dependsOn(testRepositoryCreds) -unitTest { +test { // these are tested explicitly in separate test tasks exclude '**/*CredentialsTests.class' exclude '**/S3BlobStoreRepositoryTests.class' diff --git a/qa/die-with-dignity/build.gradle b/qa/die-with-dignity/build.gradle index 3b2e21fd557e7..140df6e283ab8 100644 --- a/qa/die-with-dignity/build.gradle +++ b/qa/die-with-dignity/build.gradle @@ -27,11 +27,11 @@ esplugin { integTestRunner { systemProperty 'tests.security.manager', 'false' systemProperty 'tests.system_call_filter', 'false' - systemProperty 'pidfile', "${-> integTest.getNodes().get(0).pidFile}" - systemProperty 'log', "${-> integTest.getNodes().get(0).homeDir}/logs/${-> integTest.getNodes().get(0).clusterName}_server.json" + nonInputProperties.systemProperty 'pidfile', "${-> integTest.getNodes().get(0).pidFile}" + nonInputProperties.systemProperty 'log', "${-> integTest.getNodes().get(0).homeDir}/logs/${-> integTest.getNodes().get(0).clusterName}_server.json" systemProperty 'runtime.java.home', "${project.runtimeJavaHome}" } -unitTest.enabled = false +test.enabled = false check.dependsOn integTest diff --git a/qa/evil-tests/build.gradle b/qa/evil-tests/build.gradle index 62614ca36cda6..2f9239e5c2f22 100644 --- a/qa/evil-tests/build.gradle +++ b/qa/evil-tests/build.gradle @@ -31,7 +31,7 @@ dependencies { // TODO: give each evil test its own fresh JVM for more isolation. -unitTest { +test { systemProperty 'tests.security.manager', 'false' } diff --git a/qa/full-cluster-restart/build.gradle b/qa/full-cluster-restart/build.gradle index 60c552fc100b9..bceee0ec814ac 100644 --- a/qa/full-cluster-restart/build.gradle +++ b/qa/full-cluster-restart/build.gradle @@ -92,7 +92,7 @@ for (Version version : bwcVersions.indexCompatible) { } } -unitTest.enabled = false // no unit tests for rolling upgrades, only the rest integration test +test.enabled = false // no unit tests for rolling upgrades, only the rest integration test // basic integ tests includes testing bwc against the most recent version task bwcTestSnapshots { diff --git a/qa/logging-config/build.gradle b/qa/logging-config/build.gradle index 3f6217ae717e9..6af6532d7cfb3 100644 --- a/qa/logging-config/build.gradle +++ b/qa/logging-config/build.gradle @@ -32,10 +32,10 @@ integTestCluster { } integTestRunner { - systemProperty 'tests.logfile', + nonInputProperties.systemProperty 'tests.logfile', "${ -> integTest.nodes[0].homeDir}/logs/${ -> integTest.nodes[0].clusterName }_server.log" } -unitTest { +test { systemProperty 'tests.security.manager', 'false' } diff --git a/qa/mixed-cluster/build.gradle b/qa/mixed-cluster/build.gradle index 40ffef5e25d40..91480c4e3d244 100644 --- a/qa/mixed-cluster/build.gradle +++ b/qa/mixed-cluster/build.gradle @@ -60,7 +60,7 @@ for (Version version : bwcVersions.wireCompatible) { } } -unitTest.enabled = false // no unit tests for rolling upgrades, only the rest integration test +test.enabled = false // no unit tests for rolling upgrades, only the rest integration test // basic integ tests includes testing bwc against the most recent version task bwcTestSnapshots { diff --git a/qa/multi-cluster-search/build.gradle b/qa/multi-cluster-search/build.gradle index 0835945499d34..bca12be6754ab 100644 --- a/qa/multi-cluster-search/build.gradle +++ b/qa/multi-cluster-search/build.gradle @@ -57,6 +57,6 @@ task integTest { dependsOn = [mixedClusterTest] } -unitTest.enabled = false // no unit tests for multi-cluster-search, only integration tests +test.enabled = false // no unit tests for multi-cluster-search, only integration tests check.dependsOn(integTest) diff --git a/qa/rolling-upgrade/build.gradle b/qa/rolling-upgrade/build.gradle index 89d9fd1eacaf1..fae318bd93909 100644 --- a/qa/rolling-upgrade/build.gradle +++ b/qa/rolling-upgrade/build.gradle @@ -138,7 +138,7 @@ for (Version version : bwcVersions.wireCompatible) { } } -unitTest.enabled = false // no unit tests for rolling upgrades, only the rest integration test +test.enabled = false // no unit tests for rolling upgrades, only the rest integration test // basic integ tests includes testing bwc against the most recent version task bwcTestSnapshots { diff --git a/qa/unconfigured-node-name/build.gradle b/qa/unconfigured-node-name/build.gradle index 5aba0562e03f6..3b0faa10a7e33 100644 --- a/qa/unconfigured-node-name/build.gradle +++ b/qa/unconfigured-node-name/build.gradle @@ -29,6 +29,6 @@ integTestCluster { } integTestRunner { - systemProperty 'tests.logfile', + nonInputProperties.systemProperty 'tests.logfile', "${ -> integTest.nodes[0].homeDir}/logs/${ -> integTest.nodes[0].clusterName }_server.json" } diff --git a/qa/vagrant/build.gradle b/qa/vagrant/build.gradle index bd5f3e7a2ac1c..ac0bfe78aadd3 100644 --- a/qa/vagrant/build.gradle +++ b/qa/vagrant/build.gradle @@ -71,7 +71,7 @@ forbiddenApisMain { } // we don't have additional tests for the tests themselves -tasks.unitTest.enabled = false +tasks.test.enabled = false // Tests are destructive and meant to run in a VM, they don't adhere to general conventions testingConventions.enabled = false diff --git a/qa/verify-version-constants/build.gradle b/qa/verify-version-constants/build.gradle index 14a6b4362f1c6..42c2195dd13fa 100644 --- a/qa/verify-version-constants/build.gradle +++ b/qa/verify-version-constants/build.gradle @@ -52,7 +52,7 @@ for (Version version : bwcVersions.indexCompatible) { bwcTest.dependsOn(versionBwcTest) } -unitTest.enabled = false +test.enabled = false task bwcTestSnapshots { if (project.bwc_tests_enabled) { diff --git a/qa/wildfly/build.gradle b/qa/wildfly/build.gradle index fce27e6ab8a36..f9e43bd45fc5b 100644 --- a/qa/wildfly/build.gradle +++ b/qa/wildfly/build.gradle @@ -211,7 +211,7 @@ if (!Os.isFamily(Os.FAMILY_WINDOWS)) { check.dependsOn(integTest) -unitTest.enabled = false +test.enabled = false dependencyLicenses.enabled = false dependenciesInfo.enabled = false diff --git a/rest-api-spec/build.gradle b/rest-api-spec/build.gradle index 915c3a68f6e0e..d95ad476682b1 100644 --- a/rest-api-spec/build.gradle +++ b/rest-api-spec/build.gradle @@ -2,5 +2,5 @@ apply plugin: 'elasticsearch.build' apply plugin: 'nebula.maven-base-publish' apply plugin: 'nebula.maven-scm' -unitTest.enabled = false +test.enabled = false jarHell.enabled = false diff --git a/server/build.gradle b/server/build.gradle index 4fc8c451c9b96..50f142cddc1dd 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -17,8 +17,6 @@ * under the License. */ -import com.carrotsearch.gradle.junit4.RandomizedTestingTask - apply plugin: 'elasticsearch.build' apply plugin: 'nebula.optional-base' apply plugin: 'nebula.maven-base-publish' @@ -331,14 +329,15 @@ dependencyLicenses { } if (isEclipse == false || project.path == ":server-tests") { - task integTest(type: RandomizedTestingTask, - group: JavaBasePlugin.VERIFICATION_GROUP, - description: 'Multi-node tests', - dependsOn: unitTest.dependsOn) { + task integTest(type: Test) { + description = 'Multi-node tests' + mustRunAfter test + include '**/*IT.class' } + check.dependsOn integTest - integTest.mustRunAfter test + task internalClusterTest { dependsOn integTest } diff --git a/server/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy b/server/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy index a4a33426a43ce..d6b15f3df43dc 100644 --- a/server/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy +++ b/server/src/main/resources/org/elasticsearch/bootstrap/test-framework.policy @@ -56,6 +56,8 @@ grant codeBase "${codebase.randomizedtesting-runner}" { grant codeBase "${codebase.junit}" { // needed for TestClass creation permission java.lang.RuntimePermission "accessDeclaredMembers"; + // needed for test listener notifications + permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; }; grant codeBase "${codebase.mocksocket}" { @@ -86,3 +88,20 @@ grant codeBase "${codebase.httpasyncclient}" { // rest client uses system properties which gets the default proxy permission java.net.NetPermission "getProxySelector"; }; + +grant codeBase "file:${gradle.dist.lib}/-" { + // gradle test worker code needs a slew of permissions, we give full access here since gradle isn't a production + // dependency and there's no point in exercising the security policy against it + permission java.security.AllPermission; +}; + +grant codeBase "file:${gradle.worker.jar}" { + // gradle test worker code needs a slew of permissions, we give full access here since gradle isn't a production + // dependency and there's no point in exercising the security policy against it + permission java.security.AllPermission; +}; + +grant { + // since the gradle test worker jar is on the test classpath, our tests should be able to read it + permission java.io.FilePermission "${gradle.worker.jar}", "read"; +}; \ No newline at end of file diff --git a/test/fixtures/hdfs-fixture/build.gradle b/test/fixtures/hdfs-fixture/build.gradle index bd2dbec6649ab..5dab9d99915b5 100644 --- a/test/fixtures/hdfs-fixture/build.gradle +++ b/test/fixtures/hdfs-fixture/build.gradle @@ -23,5 +23,5 @@ dependencies { compile "org.apache.hadoop:hadoop-minicluster:2.8.1" } -unitTest.enabled = false +test.enabled = false thirdPartyAudit.enabled = false diff --git a/test/fixtures/krb5kdc-fixture/build.gradle b/test/fixtures/krb5kdc-fixture/build.gradle index 1d224942f1862..9787c3527af71 100644 --- a/test/fixtures/krb5kdc-fixture/build.gradle +++ b/test/fixtures/krb5kdc-fixture/build.gradle @@ -53,4 +53,4 @@ buildFixture.enabled = false project.ext.krb5Conf = { service -> file("$buildDir/shared/${service}/krb5.conf") } project.ext.krb5Keytabs = { service, fileName -> file("$buildDir/shared/${service}/keytabs/${fileName}") } -unitTest.enabled = false +test.enabled = false diff --git a/test/fixtures/old-elasticsearch/build.gradle b/test/fixtures/old-elasticsearch/build.gradle index 82948a0b3b05a..5cfc02bbba3c6 100644 --- a/test/fixtures/old-elasticsearch/build.gradle +++ b/test/fixtures/old-elasticsearch/build.gradle @@ -24,7 +24,7 @@ a "ports" file with the port on which Elasticsearch is running. """ apply plugin: 'elasticsearch.build' -unitTest.enabled = false +test.enabled = false dependencies { // Just for the constants.... diff --git a/test/framework/build.gradle b/test/framework/build.gradle index fbc87988837cc..094c574e05188 100644 --- a/test/framework/build.gradle +++ b/test/framework/build.gradle @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ -import com.carrotsearch.gradle.junit4.RandomizedTestingTask; dependencies { compile "org.elasticsearch.client:elasticsearch-rest-client:${version}" @@ -64,12 +63,12 @@ thirdPartyAudit.ignoreMissingClasses ( 'org.jmock.core.Constraint' ) -unitTest { +test { systemProperty 'tests.gradle_index_compat_versions', bwcVersions.indexCompatible.join(',') systemProperty 'tests.gradle_wire_compat_versions', bwcVersions.wireCompatible.join(',') systemProperty 'tests.gradle_unreleased_versions', bwcVersions.unreleased.join(',') } -task integTest(type: RandomizedTestingTask) { +task integTest(type: Test) { include "**/*IT.class" } diff --git a/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java b/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java index 28170c827b3e9..e035b779b3f02 100644 --- a/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java +++ b/test/framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java @@ -37,6 +37,7 @@ import java.io.InputStream; import java.net.SocketPermission; import java.net.URL; +import java.nio.file.Files; import java.nio.file.Path; import java.security.Permission; import java.security.Permissions; @@ -252,9 +253,12 @@ static Set parseClassPathWithSymlinks() throws Exception { Set raw = JarHell.parseClassPath(); Set cooked = new HashSet<>(raw.size()); for (URL url : raw) { - boolean added = cooked.add(PathUtils.get(url.toURI()).toRealPath().toUri().toURL()); - if (added == false) { - throw new IllegalStateException("Duplicate in classpath after resolving symlinks: " + url); + Path path = PathUtils.get(url.toURI()); + if (Files.exists(path)) { + boolean added = cooked.add(path.toRealPath().toUri().toURL()); + if (added == false) { + throw new IllegalStateException("Duplicate in classpath after resolving symlinks: " + url); + } } } return raw; diff --git a/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java b/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java index 58e126b4bed4a..b1a4c42cbfd8e 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java +++ b/test/framework/src/main/java/org/elasticsearch/test/junit/listeners/ReproduceInfoPrinter.java @@ -19,7 +19,6 @@ package org.elasticsearch.test.junit.listeners; import com.carrotsearch.randomizedtesting.ReproduceErrorMessageBuilder; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.util.Constants; @@ -38,6 +37,7 @@ import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_ITERATIONS; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_PREFIX; +import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TESTCLASS; import static com.carrotsearch.randomizedtesting.SysGlobals.SYSPROP_TESTMETHOD; import static org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase.REST_TESTS_BLACKLIST; import static org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase.REST_TESTS_SUITE; @@ -77,8 +77,14 @@ public void testFailure(Failure failure) throws Exception { final String gradlew = Constants.WINDOWS ? "gradlew" : "./gradlew"; final StringBuilder b = new StringBuilder("REPRODUCE WITH: " + gradlew + " "); String task = System.getProperty("tests.task"); - // TODO: enforce (intellij still runs the runner?) or use default "test" but that won't work for integ + + // append Gradle test runner test filter string b.append(task); + b.append(" --tests \""); + b.append(failure.getDescription().getClassName()); + b.append("."); + b.append(failure.getDescription().getMethodName()); + b.append("\""); GradleMessageBuilder gradleMessageBuilder = new GradleMessageBuilder(b); gradleMessageBuilder.appendAllOpts(failure.getDescription()); @@ -106,11 +112,6 @@ public GradleMessageBuilder(StringBuilder b) { public ReproduceErrorMessageBuilder appendAllOpts(Description description) { super.appendAllOpts(description); - if (description.getMethodName() != null) { - //prints out the raw method description instead of methodName(description) which filters out the parameters - super.appendOpt(SYSPROP_TESTMETHOD(), "\"" + description.getMethodName() + "\""); - } - return appendESProperties(); } @@ -128,6 +129,11 @@ public ReproduceErrorMessageBuilder appendOpt(String sysPropName, String value) if (sysPropName.equals(SYSPROP_ITERATIONS())) { // we don't want the iters to be in there! return this; } + if (sysPropName.equals(SYSPROP_TESTCLASS())) { + //don't print out the test class, we print it ourselves in appendAllOpts + //without filtering out the parameters (needed for REST tests) + return this; + } if (sysPropName.equals(SYSPROP_TESTMETHOD())) { //don't print out the test method, we print it ourselves in appendAllOpts //without filtering out the parameters (needed for REST tests) @@ -143,7 +149,7 @@ public ReproduceErrorMessageBuilder appendOpt(String sysPropName, String value) return this; } - public ReproduceErrorMessageBuilder appendESProperties() { + private ReproduceErrorMessageBuilder appendESProperties() { appendProperties("tests.es.logger.level"); if (inVerifyPhase()) { // these properties only make sense for integration tests diff --git a/x-pack/plugin/ccr/build.gradle b/x-pack/plugin/ccr/build.gradle index e1ddb2f12d78b..12ddcd3995b10 100644 --- a/x-pack/plugin/ccr/build.gradle +++ b/x-pack/plugin/ccr/build.gradle @@ -1,5 +1,3 @@ -import com.carrotsearch.gradle.junit4.RandomizedTestingTask - evaluationDependsOn(xpackModule('core')) apply plugin: 'elasticsearch.esplugin' @@ -21,28 +19,27 @@ compileTestJava.options.compilerArgs << "-Xlint:-try" // Integration Test classes that cannot run with the security manager String[] noSecurityManagerITClasses = [ "**/CloseFollowerIndexIT.class" ] +task internalClusterTestNoSecurityManager(type: Test) { + description = 'Java fantasy integration tests with no security manager' + + include noSecurityManagerITClasses + systemProperty 'es.set.netty.runtime.available.processors', 'false' + systemProperty 'tests.security.manager', 'false' +} + // Instead we create a separate task to run the // tests based on ESIntegTestCase -task internalClusterTest(type: RandomizedTestingTask, - group: JavaBasePlugin.VERIFICATION_GROUP, - description: 'Java fantasy integration tests', - dependsOn: unitTest.dependsOn) { +task internalClusterTest(type: Test) { + description = 'Java fantasy integration tests' + dependsOn internalClusterTestNoSecurityManager + mustRunAfter test + include '**/*IT.class' exclude noSecurityManagerITClasses systemProperty 'es.set.netty.runtime.available.processors', 'false' } -check.dependsOn internalClusterTest -internalClusterTest.mustRunAfter test -task internalClusterTestNoSecurityManager(type: RandomizedTestingTask, - group: JavaBasePlugin.VERIFICATION_GROUP, - description: 'Java fantasy integration tests with no security manager', - dependsOn: unitTest.dependsOn) { - include noSecurityManagerITClasses - systemProperty 'es.set.netty.runtime.available.processors', 'false' - systemProperty 'tests.security.manager', 'false' -} -internalClusterTest.dependsOn internalClusterTestNoSecurityManager +check.dependsOn internalClusterTest // add all sub-projects of the qa sub-project gradle.projectsEvaluated { diff --git a/x-pack/plugin/ccr/qa/build.gradle b/x-pack/plugin/ccr/qa/build.gradle index a70f1cbd0a738..d3e95d997c3fb 100644 --- a/x-pack/plugin/ccr/qa/build.gradle +++ b/x-pack/plugin/ccr/qa/build.gradle @@ -1,7 +1,7 @@ import org.elasticsearch.gradle.test.RestIntegTestTask apply plugin: 'elasticsearch.build' -unitTest.enabled = false +test.enabled = false dependencies { compile project(':test:framework') diff --git a/x-pack/plugin/ccr/qa/downgrade-to-basic-license/build.gradle b/x-pack/plugin/ccr/qa/downgrade-to-basic-license/build.gradle index bba9709087a56..cbf30b54d5fdb 100644 --- a/x-pack/plugin/ccr/qa/downgrade-to-basic-license/build.gradle +++ b/x-pack/plugin/ccr/qa/downgrade-to-basic-license/build.gradle @@ -53,11 +53,11 @@ followClusterTestCluster { followClusterTestRunner { systemProperty 'java.security.policy', "file://${buildDir}/tmp/java.policy" systemProperty 'tests.target_cluster', 'follow' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'log', "${-> followClusterTest.getNodes().get(0).homeDir}/logs/" + + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'log', "${-> followClusterTest.getNodes().get(0).homeDir}/logs/" + "${-> followClusterTest.getNodes().get(0).clusterName}_server.json" finalizedBy 'leaderClusterTestCluster#stop' } check.dependsOn followClusterTest -unitTest.enabled = false // no unit tests for multi-cluster-search, only the rest integration test +test.enabled = false // no unit tests for multi-cluster-search, only the rest integration test diff --git a/x-pack/plugin/ccr/qa/multi-cluster/build.gradle b/x-pack/plugin/ccr/qa/multi-cluster/build.gradle index 5680eb41f3877..7c9c581c5be19 100644 --- a/x-pack/plugin/ccr/qa/multi-cluster/build.gradle +++ b/x-pack/plugin/ccr/qa/multi-cluster/build.gradle @@ -36,7 +36,7 @@ middleClusterTestCluster { middleClusterTestRunner { systemProperty 'tests.target_cluster', 'middle' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" } task followClusterTest(type: RestIntegTestTask) {} @@ -54,11 +54,11 @@ followClusterTestCluster { followClusterTestRunner { systemProperty 'tests.target_cluster', 'follow' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.middle_host', "${-> middleClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.middle_host', "${-> middleClusterTest.nodes.get(0).httpUri()}" finalizedBy 'leaderClusterTestCluster#stop' finalizedBy 'middleClusterTestCluster#stop' } check.dependsOn followClusterTest -unitTest.enabled = false // no unit tests for multi-cluster-search, only the rest integration test +test.enabled = false // no unit tests for multi-cluster-search, only the rest integration test diff --git a/x-pack/plugin/ccr/qa/non-compliant-license/build.gradle b/x-pack/plugin/ccr/qa/non-compliant-license/build.gradle index d3044f760faf7..6d294c4075595 100644 --- a/x-pack/plugin/ccr/qa/non-compliant-license/build.gradle +++ b/x-pack/plugin/ccr/qa/non-compliant-license/build.gradle @@ -33,9 +33,9 @@ followClusterTestCluster { followClusterTestRunner { systemProperty 'tests.target_cluster', 'follow' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" finalizedBy 'leaderClusterTestCluster#stop' } check.dependsOn followClusterTest -unitTest.enabled = false +test.enabled = false diff --git a/x-pack/plugin/ccr/qa/rest/build.gradle b/x-pack/plugin/ccr/qa/rest/build.gradle index c890064504b51..b06535a17c096 100644 --- a/x-pack/plugin/ccr/qa/rest/build.gradle +++ b/x-pack/plugin/ccr/qa/rest/build.gradle @@ -37,4 +37,4 @@ restTestCluster { } check.dependsOn restTest -unitTest.enabled = false +test.enabled = false diff --git a/x-pack/plugin/ccr/qa/restart/build.gradle b/x-pack/plugin/ccr/qa/restart/build.gradle index 59082d7819533..8501de714fae6 100644 --- a/x-pack/plugin/ccr/qa/restart/build.gradle +++ b/x-pack/plugin/ccr/qa/restart/build.gradle @@ -35,7 +35,7 @@ followClusterTestCluster { followClusterTestRunner { systemProperty 'tests.target_cluster', 'follow' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" } task followClusterRestartTest(type: RestIntegTestTask) {} @@ -53,9 +53,9 @@ followClusterRestartTestCluster { followClusterRestartTestRunner { systemProperty 'tests.target_cluster', 'follow-restart' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" finalizedBy 'leaderClusterTestCluster#stop' } check.dependsOn followClusterRestartTest -unitTest.enabled = false +test.enabled = false diff --git a/x-pack/plugin/ccr/qa/security/build.gradle b/x-pack/plugin/ccr/qa/security/build.gradle index e1a735e0b2668..0e082f51d71a1 100644 --- a/x-pack/plugin/ccr/qa/security/build.gradle +++ b/x-pack/plugin/ccr/qa/security/build.gradle @@ -68,9 +68,9 @@ followClusterTestCluster { followClusterTestRunner { systemProperty 'tests.target_cluster', 'follow' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" finalizedBy 'leaderClusterTestCluster#stop' } check.dependsOn followClusterTest -unitTest.enabled = false // no unit tests for multi-cluster-search, only the rest integration test +test.enabled = false // no unit tests for multi-cluster-search, only the rest integration test diff --git a/x-pack/plugin/core/build.gradle b/x-pack/plugin/core/build.gradle index ed61fc9e3e703..7a6673643879a 100644 --- a/x-pack/plugin/core/build.gradle +++ b/x-pack/plugin/core/build.gradle @@ -2,7 +2,6 @@ import org.elasticsearch.gradle.MavenFilteringHack import java.nio.file.Files import java.nio.file.Paths -import com.carrotsearch.gradle.junit4.RandomizedTestingTask; apply plugin: 'elasticsearch.esplugin' apply plugin: 'nebula.maven-base-publish' @@ -99,7 +98,7 @@ sourceSets.test.java { srcDir '../../license-tools/src/main/java' } -unitTest { +test { /* * We have to disable setting the number of available processors as tests in the same JVM randomize processors and will step on each * other if we allow them to set the number of available processors as it's set-once in Netty. @@ -139,6 +138,6 @@ thirdPartyAudit.ignoreMissingClasses ( integTest.enabled = false // There are some integ tests that don't require a cluster, we still want to run those -task internalClusterTest(type: RandomizedTestingTask) { +task internalClusterTest(type: Test) { include "**/*IT.class" } diff --git a/x-pack/plugin/ilm/qa/build.gradle b/x-pack/plugin/ilm/qa/build.gradle index f2f60527ec4c1..74412a094b489 100644 --- a/x-pack/plugin/ilm/qa/build.gradle +++ b/x-pack/plugin/ilm/qa/build.gradle @@ -1,7 +1,7 @@ import org.elasticsearch.gradle.test.RestIntegTestTask apply plugin: 'elasticsearch.build' -unitTest.enabled = false +test.enabled = false dependencies { compile project(':test:framework') diff --git a/x-pack/plugin/ilm/qa/multi-cluster/build.gradle b/x-pack/plugin/ilm/qa/multi-cluster/build.gradle index d4c24d0195ef6..76dbf676d738f 100644 --- a/x-pack/plugin/ilm/qa/multi-cluster/build.gradle +++ b/x-pack/plugin/ilm/qa/multi-cluster/build.gradle @@ -50,12 +50,12 @@ followClusterTestCluster { followClusterTestRunner { systemProperty 'tests.target_cluster', 'follow' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" /* To support taking index snapshots, we have to set path.repo setting */ systemProperty 'tests.path.repo', new File(buildDir, "cluster/shared/repo") finalizedBy 'leaderClusterTestCluster#stop' } check.dependsOn followClusterTest -unitTest.enabled = false // no unit tests for this module, only the rest integration test +test.enabled = false // no unit tests for this module, only the rest integration test diff --git a/x-pack/plugin/ilm/qa/rest/build.gradle b/x-pack/plugin/ilm/qa/rest/build.gradle index 7a79d1c20d936..c69a3dfce2143 100644 --- a/x-pack/plugin/ilm/qa/rest/build.gradle +++ b/x-pack/plugin/ilm/qa/rest/build.gradle @@ -42,4 +42,4 @@ restTestCluster { } check.dependsOn restTest -unitTest.enabled = false +test.enabled = false diff --git a/x-pack/plugin/ml/build.gradle b/x-pack/plugin/ml/build.gradle index 0fe0af236f9ad..6ca1a44c145da 100644 --- a/x-pack/plugin/ml/build.gradle +++ b/x-pack/plugin/ml/build.gradle @@ -1,5 +1,3 @@ -import com.carrotsearch.gradle.junit4.RandomizedTestingTask - evaluationDependsOn(xpackModule('core')) apply plugin: 'elasticsearch.esplugin' @@ -94,12 +92,11 @@ integTest.enabled = false // Instead we create a separate task to run the // tests based on ESIntegTestCase -task internalClusterTest(type: RandomizedTestingTask, - group: JavaBasePlugin.VERIFICATION_GROUP, - description: 'Multi-node tests', - dependsOn: unitTest.dependsOn) { - include '**/*IT.class' - systemProperty 'es.set.netty.runtime.available.processors', 'false' +task internalClusterTest(type: Test) { + description = 'Multi-node tests' + + include '**/*IT.class' + systemProperty 'es.set.netty.runtime.available.processors', 'false' } check.dependsOn internalClusterTest internalClusterTest.mustRunAfter test diff --git a/x-pack/plugin/monitoring/build.gradle b/x-pack/plugin/monitoring/build.gradle index 9341a957797ba..8b6f07787fbc1 100644 --- a/x-pack/plugin/monitoring/build.gradle +++ b/x-pack/plugin/monitoring/build.gradle @@ -1,5 +1,3 @@ -import com.carrotsearch.gradle.junit4.RandomizedTestingTask - evaluationDependsOn(xpackModule('core')) apply plugin: 'elasticsearch.esplugin' @@ -58,15 +56,15 @@ integTest.enabled = false // Instead we create a separate task to run the // tests based on ESIntegTestCase -task internalClusterTest(type: RandomizedTestingTask, - group: JavaBasePlugin.VERIFICATION_GROUP, - description: 'Multi-node tests', - dependsOn: unitTest.dependsOn) { - include '**/*IT.class' - systemProperty 'es.set.netty.runtime.available.processors', 'false' +task internalClusterTest(type: Test) { + description = 'Multi-node tests' + mustRunAfter test + + include '**/*IT.class' + systemProperty 'es.set.netty.runtime.available.processors', 'false' } + check.dependsOn internalClusterTest -internalClusterTest.mustRunAfter test // also add an "alias" task to make typing on the command line easier task icTest { task icTest { diff --git a/x-pack/plugin/security/build.gradle b/x-pack/plugin/security/build.gradle index 63b531b1f3319..8ea14c5f6dd2e 100644 --- a/x-pack/plugin/security/build.gradle +++ b/x-pack/plugin/security/build.gradle @@ -304,7 +304,7 @@ run { plugin xpackModule('core') } -unitTest { +test { /* * We have to disable setting the number of available processors as tests in the same JVM randomize processors and will step on each * other if we allow them to set the number of available processors as it's set-once in Netty. diff --git a/x-pack/plugin/security/cli/build.gradle b/x-pack/plugin/security/cli/build.gradle index 1a829704d40bc..19a8d11dd6f0c 100644 --- a/x-pack/plugin/security/cli/build.gradle +++ b/x-pack/plugin/security/cli/build.gradle @@ -23,7 +23,7 @@ dependencyLicenses { } if (project.inFipsJvm) { - unitTest.enabled = false + test.enabled = false testingConventions.enabled = false // Forbiden APIs non-portable checks fail because bouncy castle classes being used from the FIPS JDK since those are // not part of the Java specification - all of this is as designed, so we have to relax this check for FIPS. diff --git a/x-pack/plugin/sql/build.gradle b/x-pack/plugin/sql/build.gradle index 31cec8bbee39f..c4719aef04ab8 100644 --- a/x-pack/plugin/sql/build.gradle +++ b/x-pack/plugin/sql/build.gradle @@ -1,5 +1,3 @@ -import com.carrotsearch.gradle.junit4.RandomizedTestingTask - evaluationDependsOn(xpackModule('core')) apply plugin: 'elasticsearch.esplugin' @@ -30,14 +28,13 @@ archivesBaseName = 'x-pack-sql' // All integration tests live in qa modules integTest.enabled = false -task internalClusterTest(type: RandomizedTestingTask, - group: JavaBasePlugin.VERIFICATION_GROUP, - dependsOn: unitTest.dependsOn) { +task internalClusterTest(type: Test) { + mustRunAfter test include '**/*IT.class' systemProperty 'es.set.netty.runtime.available.processors', 'false' } + check.dependsOn internalClusterTest -internalClusterTest.mustRunAfter test dependencies { // "org.elasticsearch.plugin:x-pack-core:${version}" doesn't work with idea because the testArtifacts are also here diff --git a/x-pack/plugin/sql/jdbc/build.gradle b/x-pack/plugin/sql/jdbc/build.gradle index bec79dabb1465..3c7eb6b804b5a 100644 --- a/x-pack/plugin/sql/jdbc/build.gradle +++ b/x-pack/plugin/sql/jdbc/build.gradle @@ -37,7 +37,7 @@ dependencyLicenses { ignoreSha 'elasticsearch' } -unitTest { +test { // don't use the shaded jar for tests classpath += project.tasks.compileJava.outputs.files classpath -= project.tasks.shadowJar.outputs.files diff --git a/x-pack/plugin/sql/qa/build.gradle b/x-pack/plugin/sql/qa/build.gradle index cf0a0dba8ee62..4c9fa6de03095 100644 --- a/x-pack/plugin/sql/qa/build.gradle +++ b/x-pack/plugin/sql/qa/build.gradle @@ -30,7 +30,7 @@ dependencies { /* disable unit tests because these are all integration tests used * other qa projects. */ -unitTest.enabled = false +test.enabled = false dependencyLicenses.enabled = false dependenciesInfo.enabled = false diff --git a/x-pack/plugin/sql/qa/security/build.gradle b/x-pack/plugin/sql/qa/security/build.gradle index 45ab8c92f1e7f..50ba4dbf4382c 100644 --- a/x-pack/plugin/sql/qa/security/build.gradle +++ b/x-pack/plugin/sql/qa/security/build.gradle @@ -42,9 +42,9 @@ subprojects { integTestRunner { def today = new Date().format('yyyy-MM-dd') - systemProperty 'tests.audit.logfile', + nonInputProperties.systemProperty 'tests.audit.logfile', "${ -> integTest.nodes[0].homeDir}/logs/${ -> integTest.nodes[0].clusterName }_audit.json" - systemProperty 'tests.audit.yesterday.logfile', + nonInputProperties.systemProperty 'tests.audit.yesterday.logfile', "${ -> integTest.nodes[0].homeDir}/logs/${ -> integTest.nodes[0].clusterName }_audit-${today}.json" } diff --git a/x-pack/plugin/sql/sql-cli/build.gradle b/x-pack/plugin/sql/sql-cli/build.gradle index e519062e14f57..6f57ea279c5ab 100644 --- a/x-pack/plugin/sql/sql-cli/build.gradle +++ b/x-pack/plugin/sql/sql-cli/build.gradle @@ -106,7 +106,7 @@ task runcli { } // Use the jar for testing so we can get the proper version information -unitTest { +test { classpath -= compileJava.outputs.files classpath -= configurations.compile classpath -= configurations.runtime diff --git a/x-pack/plugin/watcher/build.gradle b/x-pack/plugin/watcher/build.gradle index a32a88aaf06e5..8d7c2e06303df 100644 --- a/x-pack/plugin/watcher/build.gradle +++ b/x-pack/plugin/watcher/build.gradle @@ -115,7 +115,7 @@ run { plugin xpackModule('core') } -unitTest { +test { /* * We have to disable setting the number of available processors as tests in the same JVM randomize processors and will step on each * other if we allow them to set the number of available processors as it's set-once in Netty. diff --git a/x-pack/qa/evil-tests/build.gradle b/x-pack/qa/evil-tests/build.gradle index ad32645b3647c..d411909fb310b 100644 --- a/x-pack/qa/evil-tests/build.gradle +++ b/x-pack/qa/evil-tests/build.gradle @@ -5,7 +5,7 @@ dependencies { testCompile project(path: xpackModule('security'), configuration: 'testArtifacts') } -unitTest { +test { systemProperty 'tests.security.manager', 'false' include '**/*Tests.class' } diff --git a/x-pack/qa/full-cluster-restart/build.gradle b/x-pack/qa/full-cluster-restart/build.gradle index 40dca76abc913..f3f290c63e121 100644 --- a/x-pack/qa/full-cluster-restart/build.gradle +++ b/x-pack/qa/full-cluster-restart/build.gradle @@ -7,7 +7,7 @@ import java.nio.charset.StandardCharsets // Apply the java plugin to this project so the sources can be edited in an IDE apply plugin: 'elasticsearch.standalone-test' -unitTest.enabled = false +test.enabled = false dependencies { // "org.elasticsearch.plugin:x-pack-core:${version}" doesn't work with idea because the testArtifacts are also here @@ -70,15 +70,19 @@ Closure waitWithAuth = { NodeInfo node, AntBuilder ant -> return tmpFile.exists() } -String coreFullClusterRestartPath = project(':qa:full-cluster-restart').projectDir.toPath().resolve('src/test/java').toString() sourceSets { - test { + testLib { java { - srcDirs += [coreFullClusterRestartPath] + srcDir(project(':qa:full-cluster-restart').projectDir.toPath().resolve('src/test/java').toString()) } } + test { + compileClasspath += testLib.output + } } +configurations.testLibCompile.extendsFrom configurations.testCompile + licenseHeaders { approvedLicenses << 'Apache' } diff --git a/x-pack/qa/multi-cluster-search-security/build.gradle b/x-pack/qa/multi-cluster-search-security/build.gradle index 63265b6949f1e..c31b2c0ad1d5e 100644 --- a/x-pack/qa/multi-cluster-search-security/build.gradle +++ b/x-pack/qa/multi-cluster-search-security/build.gradle @@ -75,5 +75,5 @@ task integTest { dependsOn = [mixedClusterTest] } -unitTest.enabled = false // no unit tests for multi-cluster-search, only the rest integration test +test.enabled = false // no unit tests for multi-cluster-search, only the rest integration test check.dependsOn(integTest) diff --git a/x-pack/qa/rolling-upgrade-basic/build.gradle b/x-pack/qa/rolling-upgrade-basic/build.gradle index 5b7cad500361c..169ff9c8b154e 100644 --- a/x-pack/qa/rolling-upgrade-basic/build.gradle +++ b/x-pack/qa/rolling-upgrade-basic/build.gradle @@ -120,7 +120,7 @@ for (Version version : bwcVersions.wireCompatible) { } } -unitTest.enabled = false // no unit tests for rolling upgrades, only the rest integration test +test.enabled = false // no unit tests for rolling upgrades, only the rest integration test // basic integ tests includes testing bwc against the most recent version task bwcTestSnapshots { diff --git a/x-pack/qa/rolling-upgrade-multi-cluster/build.gradle b/x-pack/qa/rolling-upgrade-multi-cluster/build.gradle index 144b410391867..19e1f5a716c08 100644 --- a/x-pack/qa/rolling-upgrade-multi-cluster/build.gradle +++ b/x-pack/qa/rolling-upgrade-multi-cluster/build.gradle @@ -45,8 +45,8 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'none' systemProperty 'tests.rest.cluster_name', 'leader' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" } // ============================================================================================ @@ -76,11 +76,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'none' systemProperty 'tests.rest.cluster_name', 'follower' - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" - systemProperty 'tests.follower_host', "${-> followerClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerClusterTest.nodes.get(0).transportUri()}" } // ============================================================================================ @@ -119,11 +119,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'one_third' systemProperty 'tests.rest.cluster_name', 'follower' - systemProperty 'tests.follower_host', "${-> followerClusterTest.nodes.get(1).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerClusterTest.nodes.get(1).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerClusterTest.nodes.get(1).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerClusterTest.nodes.get(1).transportUri()}" - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" finalizedBy "${taskPrefix}#follower#clusterTestCluster#node1.stop" } @@ -140,11 +140,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'two_third' systemProperty 'tests.rest.cluster_name', 'follower' - systemProperty 'tests.follower_host', "${-> followerClusterTest.nodes.get(2).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerClusterTest.nodes.get(2).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerClusterTest.nodes.get(2).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerClusterTest.nodes.get(2).transportUri()}" - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" finalizedBy "${taskPrefix}#follower#clusterTestCluster#node2.stop" } @@ -161,11 +161,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'all' systemProperty 'tests.rest.cluster_name', 'follower' - systemProperty 'tests.follower_host', "${-> followerOneThirdUpgradedTest.nodes.get(0).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerOneThirdUpgradedTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerOneThirdUpgradedTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerOneThirdUpgradedTest.nodes.get(0).transportUri()}" - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(0).transportUri()}" // This is needed, otherwise leader node 0 will stop after the leaderClusterTestRunner task has run. // Here it is ok to stop, because in the next task, the leader node 0 gets upgraded. @@ -188,11 +188,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'one_third' systemProperty 'tests.rest.cluster_name', 'leader' - systemProperty 'tests.follower_host', "${-> followerUpgradedClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerUpgradedClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerUpgradedClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerUpgradedClusterTest.nodes.get(0).transportUri()}" - systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(2).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(2).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderClusterTest.nodes.get(2).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderClusterTest.nodes.get(2).transportUri()}" finalizedBy "${taskPrefix}#leader#clusterTestCluster#node1.stop" } @@ -209,11 +209,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'two_third' systemProperty 'tests.rest.cluster_name', 'leader' - systemProperty 'tests.follower_host', "${-> followerUpgradedClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerUpgradedClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerUpgradedClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerUpgradedClusterTest.nodes.get(0).transportUri()}" - systemProperty 'tests.leader_host', "${-> leaderOneThirdUpgradedTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderOneThirdUpgradedTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderOneThirdUpgradedTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderOneThirdUpgradedTest.nodes.get(0).transportUri()}" finalizedBy "${taskPrefix}#leader#clusterTestCluster#node2.stop" } @@ -230,11 +230,11 @@ for (Version version : bwcVersions.wireCompatible) { systemProperty 'tests.rest.upgrade_state', 'all' systemProperty 'tests.rest.cluster_name', 'leader' - systemProperty 'tests.follower_host', "${-> followerUpgradedClusterTest.nodes.get(0).httpUri()}" - systemProperty 'tests.follower_remote_cluster_seed', "${-> followerUpgradedClusterTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.follower_host', "${-> followerUpgradedClusterTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.follower_remote_cluster_seed', "${-> followerUpgradedClusterTest.nodes.get(0).transportUri()}" - systemProperty 'tests.leader_host', "${-> leaderTwoThirdsUpgradedTest.nodes.get(0).httpUri()}" - systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderTwoThirdsUpgradedTest.nodes.get(0).transportUri()}" + nonInputProperties.systemProperty 'tests.leader_host', "${-> leaderTwoThirdsUpgradedTest.nodes.get(0).httpUri()}" + nonInputProperties.systemProperty 'tests.leader_remote_cluster_seed', "${-> leaderTwoThirdsUpgradedTest.nodes.get(0).transportUri()}" /* * Force stopping all the upgraded nodes after the test runner @@ -255,7 +255,7 @@ for (Version version : bwcVersions.wireCompatible) { } } -unitTest.enabled = false // no unit tests for rolling upgrades, only the rest integration test +test.enabled = false // no unit tests for rolling upgrades, only the rest integration test // basic integ tests includes testing bwc against the most recent version task integTest { diff --git a/x-pack/qa/rolling-upgrade/build.gradle b/x-pack/qa/rolling-upgrade/build.gradle index 0cdbbe71e55ba..cabccc72cf753 100644 --- a/x-pack/qa/rolling-upgrade/build.gradle +++ b/x-pack/qa/rolling-upgrade/build.gradle @@ -7,7 +7,7 @@ import java.nio.charset.StandardCharsets // Apply the java plugin to this project so the sources can be edited in an IDE apply plugin: 'elasticsearch.standalone-test' -unitTest.enabled = false +test.enabled = false dependencies { // "org.elasticsearch.plugin:x-pack-core:${version}" doesn't work with idea because the testArtifacts are also here diff --git a/x-pack/qa/third-party/active-directory/build.gradle b/x-pack/qa/third-party/active-directory/build.gradle index e33c0fa6d69f8..6ce8541fc431f 100644 --- a/x-pack/qa/third-party/active-directory/build.gradle +++ b/x-pack/qa/third-party/active-directory/build.gradle @@ -19,7 +19,7 @@ forbiddenPatterns { exclude '**/*.der' } -unitTest { +test { /* * We have to disable setting the number of available processors as tests in the same JVM randomize processors and will step on each * other if we allow them to set the number of available processors as it's set-once in Netty. diff --git a/x-pack/test/idp-fixture/build.gradle b/x-pack/test/idp-fixture/build.gradle index 93f5b14ad23a2..c55123e08d0f1 100644 --- a/x-pack/test/idp-fixture/build.gradle +++ b/x-pack/test/idp-fixture/build.gradle @@ -1,4 +1,4 @@ apply plugin: 'elasticsearch.build' apply plugin: 'elasticsearch.test.fixtures' -unitTest.enabled = false \ No newline at end of file +test.enabled = false \ No newline at end of file diff --git a/x-pack/test/smb-fixture/build.gradle b/x-pack/test/smb-fixture/build.gradle index 846c38829870a..5b2161de2907b 100644 --- a/x-pack/test/smb-fixture/build.gradle +++ b/x-pack/test/smb-fixture/build.gradle @@ -1,4 +1,4 @@ apply plugin: 'elasticsearch.build' apply plugin: 'elasticsearch.test.fixtures' -unitTest.enabled = false +test.enabled = false