Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions TESTING.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,10 @@ To run all verification tasks, including static checks, unit tests, and integrat
---------------------------------------------------------------------------

Note that this will also run the unit tests and precommit tasks first. If you want to just
run the integration tests (because you are debugging them):
run the in memory cluster integration tests (because you are debugging them):

---------------------------------------------------------------------------
./gradlew integTest
./gradlew internalClusterTest
---------------------------------------------------------------------------

If you want to just run the precommit checks:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import nebula.plugin.info.InfoBrokerPlugin
import org.apache.commons.io.IOUtils
import org.elasticsearch.gradle.info.BuildParams
import org.elasticsearch.gradle.info.GlobalBuildInfoPlugin
import org.elasticsearch.gradle.info.JavaHome
import org.elasticsearch.gradle.plugin.PluginBuildPlugin
import org.elasticsearch.gradle.precommit.DependencyLicensesTask
import org.elasticsearch.gradle.precommit.PrecommitTasks
Expand Down Expand Up @@ -55,13 +54,11 @@ import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.credentials.HttpHeaderCredentials
import org.gradle.api.execution.TaskActionListener
import org.gradle.api.execution.TaskExecutionGraph
import org.gradle.api.file.CopySpec
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.BasePluginConvention
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
Expand All @@ -70,16 +67,13 @@ import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.TaskProvider
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.api.tasks.testing.logging.TestLoggingContainer
import org.gradle.authentication.http.HttpHeaderAuthentication
import org.gradle.external.javadoc.CoreJavadocOptions
import org.gradle.internal.jvm.Jvm
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.process.CommandLineArgumentProvider
import org.gradle.util.GradleVersion

import java.nio.charset.StandardCharsets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,7 @@ class PrecommitTasks {
}

SourceSet sourceSet = project.sourceSets.getByName(sourceSetName)
FileCollection runtime = sourceSet.runtimeClasspath
classpath = runtime.plus(sourceSet.compileClasspath)
classpath = project.files { sourceSet.runtimeClasspath.plus(sourceSet.compileClasspath) }

targetCompatibility = BuildParams.runtimeJavaVersion.majorVersion
if (BuildParams.runtimeJavaVersion > JavaVersion.VERSION_13) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import groovy.lang.Closure;
import org.elasticsearch.gradle.util.GradleUtils;
import org.elasticsearch.gradle.util.Util;
import org.gradle.api.DefaultTask;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Task;
Expand All @@ -46,9 +47,12 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
Expand All @@ -62,6 +66,8 @@ public class TestingConventionsTasks extends DefaultTask {

private final NamedDomainObjectContainer<TestingConventionRule> naming;

private List<String> tasks = null;

public TestingConventionsTasks() {
setDescription("Tests various testing conventions");
// Run only after everything is compiled
Expand All @@ -74,15 +80,16 @@ public Map<String, Set<File>> getClassFilesPerEnabledTask() {
return getProject().getTasks()
.withType(Test.class)
.stream()
.filter(t -> tasks == null || tasks.contains(t.getName()))
.filter(Task::getEnabled)
.collect(Collectors.toMap(Task::getPath, task -> task.getCandidateClassFiles().getFiles()));
}

@Input
public Map<String, File> getTestClassNames() {
if (testClassNames == null) {
testClassNames = GradleUtils.getJavaSourceSets(getProject())
.getByName("test")
testClassNames = Util.getJavaTestSourceSet(getProject())
.get()
.getOutput()
.getClassesDirs()
.getFiles()
Expand All @@ -108,6 +115,10 @@ public void naming(Closure<TestingConventionRule> action) {
naming.configure(action);
}

public void setTasks(String... tasks) {
this.tasks = Arrays.asList(tasks);
}

@Input
public Set<String> getMainClassNamedLikeTests() {
SourceSetContainer javaSourceSets = GradleUtils.getJavaSourceSets(getProject());
Expand Down Expand Up @@ -319,6 +330,7 @@ private boolean seemsLikeATest(Class<?> clazz) {
}

private boolean implementsNamingConvention(Class<?> clazz) {
Objects.requireNonNull(clazz);
return implementsNamingConvention(clazz.getName());
}

Expand Down Expand Up @@ -349,13 +361,7 @@ private FileCollection getTestsClassPath() {
// the classes these don't influence the checks done by this task.
// A side effect is that we could mark as up-to-date with missing dependencies, but these will be found when
// running the tests.
return getProject().files(
getProject().getConfigurations().getByName("testRuntime").resolve(),
GradleUtils.getJavaSourceSets(getProject())
.stream()
.flatMap(sourceSet -> sourceSet.getOutput().getClassesDirs().getFiles().stream())
.collect(Collectors.toList())
);
return Util.getJavaTestSourceSet(getProject()).get().getRuntimeClasspath();
}

private Map<String, File> walkPathAndLoadClasses(File testRoot) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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 org.elasticsearch.gradle.test;

import org.elasticsearch.gradle.util.GradleUtils;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.tasks.SourceSet;

public class InternalClusterTestPlugin implements Plugin<Project> {

public static final String SOURCE_SET_NAME = "internalClusterTest";

@Override
public void apply(Project project) {
GradleUtils.addTestSourceSet(project, SOURCE_SET_NAME);

// TODO: fix usages of IT tests depending on Tests methods so this extension is not necessary
GradleUtils.extendSourceSet(project, SourceSet.TEST_SOURCE_SET_NAME, SOURCE_SET_NAME);

// add alias task that is easier to type
project.getTasks().register("icTest").configure(alias -> alias.dependsOn(SOURCE_SET_NAME));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,34 @@
*/
package org.elasticsearch.gradle.util;

import org.elasticsearch.gradle.ElasticsearchJavaPlugin;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.PolymorphicDomainObjectContainer;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.UnknownTaskException;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.provider.Provider;
import org.gradle.api.services.BuildService;
import org.gradle.api.services.BuildServiceRegistration;
import org.gradle.api.services.BuildServiceRegistry;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.testing.Test;
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
import org.gradle.plugins.ide.idea.model.IdeaModel;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

public abstract class GradleUtils {

Expand Down Expand Up @@ -120,4 +131,79 @@ public static <T extends BuildService<?>> Provider<T> getBuildService(BuildServi

return (Provider<T>) registration.getService();
}

/**
* Add a source set and task of the same name that runs tests.
*
* IDEs are also configured if setup, and the test task is added to check. The new test source
* set extends from the normal test source set to allow sharing of utilities.
*
* @return A task provider for the newly created test task
*/
public static TaskProvider<?> addTestSourceSet(Project project, String sourceSetName) {
project.getPluginManager().apply(ElasticsearchJavaPlugin.class);

// create our test source set and task
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
SourceSet testSourceSet = sourceSets.create(sourceSetName);
TaskProvider<Test> testTask = project.getTasks().register(sourceSetName, Test.class);
testTask.configure(task -> {
task.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
task.setTestClassesDirs(testSourceSet.getOutput().getClassesDirs());
task.setClasspath(testSourceSet.getRuntimeClasspath());
});

Configuration testCompileConfig = project.getConfigurations().getByName(testSourceSet.getCompileClasspathConfigurationName());
Configuration testRuntimeConfig = project.getConfigurations().getByName(testSourceSet.getRuntimeClasspathConfigurationName());
testSourceSet.setCompileClasspath(testCompileConfig);
testSourceSet.setRuntimeClasspath(project.getObjects().fileCollection().from(testSourceSet.getOutput(), testRuntimeConfig));

extendSourceSet(project, SourceSet.MAIN_SOURCE_SET_NAME, sourceSetName);

// setup IDEs
String runtimeClasspathName = testSourceSet.getRuntimeClasspathConfigurationName();
Configuration runtimeClasspathConfiguration = project.getConfigurations().getByName(runtimeClasspathName);
project.getPluginManager().withPlugin("idea", p -> {
IdeaModel idea = project.getExtensions().getByType(IdeaModel.class);
idea.getModule().setTestSourceDirs(testSourceSet.getJava().getSrcDirs());
idea.getModule().getScopes().put("TEST", Map.of("plus", List.of(runtimeClasspathConfiguration)));
});
project.getPluginManager().withPlugin("eclipse", p -> {
EclipseModel eclipse = project.getExtensions().getByType(EclipseModel.class);
eclipse.getClasspath().setSourceSets(List.of(testSourceSet));
eclipse.getClasspath().getPlusConfigurations().add(runtimeClasspathConfiguration);
});

// add to the check task
project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME).configure(check -> check.dependsOn(testTask));

return testTask;
}

/**
* Extend the configurations of one source set from another.
*/
public static void extendSourceSet(Project project, String parentSourceSetName, String childSourceSetName) {
final List<Function<SourceSet, String>> configNameFunctions = Arrays.asList(
SourceSet::getCompileConfigurationName,
SourceSet::getImplementationConfigurationName,
SourceSet::getRuntimeConfigurationName,
SourceSet::getRuntimeOnlyConfigurationName
);
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
SourceSet parent = sourceSets.getByName(parentSourceSetName);
SourceSet child = sourceSets.getByName(childSourceSetName);

for (Function<SourceSet, String> configNameFunction : configNameFunctions) {
String parentConfigName = configNameFunction.apply(parent);
String childConfigName = configNameFunction.apply(child);
Configuration parentConfig = project.getConfigurations().getByName(parentConfigName);
Configuration childConfig = project.getConfigurations().getByName(childConfigName);
childConfig.extendsFrom(parentConfig);
}

// tie this new test source set to the main and test source sets
child.setCompileClasspath(project.getObjects().fileCollection().from(child.getCompileClasspath(), parent.getOutput()));
child.setRuntimeClasspath(project.getObjects().fileCollection().from(child.getRuntimeClasspath(), parent.getOutput()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# 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.
#

implementation-class=org.elasticsearch.gradle.test.InternalClusterTestPlugin
18 changes: 7 additions & 11 deletions server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.elasticsearch.gradle.info.BuildParams
apply plugin: 'elasticsearch.build'
apply plugin: 'nebula.optional-base'
apply plugin: 'nebula.maven-base-publish'
apply plugin: 'elasticsearch.internal-cluster-test'

publishing {
publications {
Expand Down Expand Up @@ -134,11 +135,15 @@ dependencies {
// tests use the locally compiled version of server
exclude group: 'org.elasticsearch', module: 'server'
}
internalClusterTestCompile(project(":test:framework")) {
Copy link
Contributor

@jakelandis jakelandis Apr 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the help method setup the TestCompile dependency on :test:framework ? (admittedly, I don't know how to handle the exclude here...but i think all tests will need that dependency)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, but I'd like to consolidate that after we have converted all the xpack projects to using this plugin. For now, I want to stay simple as possible and only make it more complicated as we see universal commonalities.

exclude group: 'org.elasticsearch', module: 'server'
}

}

compileJava.options.compilerArgs << "-Xlint:-cast,-rawtypes,-unchecked"
compileTestJava.options.compilerArgs << "-Xlint:-cast,-rawtypes,-unchecked"
compileInternalClusterTestJava.options.compilerArgs << "-Xlint:-cast,-rawtypes,-unchecked"

// Until this project is always being formatted with spotless, we need to
// guard against `spotless()` not existing.
Expand Down Expand Up @@ -175,6 +180,7 @@ testingConventions {
baseClass "org.elasticsearch.test.ESSingleNodeTestCase"
}
}
tasks = ['test']
}

task generateModulesList {
Expand Down Expand Up @@ -332,20 +338,10 @@ dependencyLicenses {
}


task integTest(type: Test) {
description = 'Multi-node tests'
mustRunAfter test

include '**/*IT.class'
tasks.named('internalClusterTest').configure {
if (org.elasticsearch.gradle.info.BuildParams.isSnapshotBuild() == false) {
systemProperty 'es.datastreams_feature_enabled', 'true'
}
}

check.dependsOn integTest

task internalClusterTest {
dependsOn integTest
}


Loading