The distro test plugin was originally designed to be applied within each subproject, per operating system we run in a VM with vagrant. However, for efficiency, and also ease of having a single task to run in CI when launching within individual OS VMs, having the "destructive" tasks in a single place is more convenient. This commit reworks the distro test plugin to be applied to the qa/vagrant project, which now creates only the wrapper tasks in each of the subprojects for each vagrant VM.
This commit is contained in:
parent
7f550f2b29
commit
884f26a1dc
|
@ -30,7 +30,6 @@ import org.elasticsearch.gradle.Jdk;
|
|||
import org.elasticsearch.gradle.JdkDownloadPlugin;
|
||||
import org.elasticsearch.gradle.Version;
|
||||
import org.elasticsearch.gradle.VersionProperties;
|
||||
import org.elasticsearch.gradle.tool.Boilerplate;
|
||||
import org.elasticsearch.gradle.vagrant.BatsProgressLogger;
|
||||
import org.elasticsearch.gradle.vagrant.VagrantBasePlugin;
|
||||
import org.elasticsearch.gradle.vagrant.VagrantExtension;
|
||||
|
@ -41,7 +40,6 @@ import org.gradle.api.artifacts.Configuration;
|
|||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension;
|
||||
import org.gradle.api.plugins.JavaBasePlugin;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Copy;
|
||||
import org.gradle.api.tasks.TaskInputs;
|
||||
|
@ -52,8 +50,12 @@ import java.io.IOException;
|
|||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -66,34 +68,47 @@ public class DistroTestPlugin implements Plugin<Project> {
|
|||
|
||||
// all distributions used by distro tests. this is temporary until tests are per distribution
|
||||
private static final String PACKAGING_DISTRIBUTION = "packaging";
|
||||
private static final String COPY_PACKAGING_TASK = "copyPackagingArchives";
|
||||
private static final String COPY_DISTRIBUTIONS_TASK = "copyDistributions";
|
||||
private static final String IN_VM_SYSPROP = "tests.inVM";
|
||||
|
||||
private static Version upgradeVersion;
|
||||
private Provider<Directory> archivesDir;
|
||||
private TaskProvider<Copy> copyPackagingArchives;
|
||||
private Jdk gradleJdk;
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPluginManager().apply(JdkDownloadPlugin.class);
|
||||
project.getPluginManager().apply(DistributionDownloadPlugin.class);
|
||||
project.getPluginManager().apply(VagrantBasePlugin.class);
|
||||
project.getPluginManager().apply(JavaPlugin.class);
|
||||
|
||||
configureVM(project);
|
||||
project.getPluginManager().apply(BuildPlugin.class);
|
||||
|
||||
if (upgradeVersion == null) {
|
||||
// just read this once, since it is the same for all projects. this is safe because gradle configuration is single threaded
|
||||
upgradeVersion = getUpgradeVersion(project);
|
||||
}
|
||||
// TODO: it would be useful to also have the SYSTEM_JAVA_HOME setup in the root project, so that running from GCP only needs
|
||||
// a java for gradle to run, and the tests are self sufficient and consistent with the java they use
|
||||
|
||||
// setup task to run inside VM
|
||||
configureDistributions(project);
|
||||
configureCopyPackagingTask(project);
|
||||
configureDistroTest(project);
|
||||
configureBatsTest(project, "oss");
|
||||
configureBatsTest(project, "default");
|
||||
Version upgradeVersion = getUpgradeVersion(project);
|
||||
Provider<Directory> distributionsDir = project.getLayout().getBuildDirectory().dir("packaging/distributions");
|
||||
|
||||
configureDistributions(project, upgradeVersion);
|
||||
TaskProvider<Copy> copyDistributionsTask = configureCopyDistributionsTask(project, upgradeVersion, distributionsDir);
|
||||
|
||||
Map<String, TaskProvider<?>> distroTests = new HashMap<>();
|
||||
Map<String, TaskProvider<?>> batsTests = new HashMap<>();
|
||||
distroTests.put("distribution", configureDistroTest(project, distributionsDir, copyDistributionsTask));
|
||||
batsTests.put("bats oss", configureBatsTest(project, "oss", distributionsDir, copyDistributionsTask));
|
||||
batsTests.put("bats default", configureBatsTest(project, "default", distributionsDir, copyDistributionsTask));
|
||||
|
||||
project.subprojects(vmProject -> {
|
||||
vmProject.getPluginManager().apply(VagrantBasePlugin.class);
|
||||
vmProject.getPluginManager().apply(JdkDownloadPlugin.class);
|
||||
List<Object> vmDependencies = new ArrayList<>(configureVM(vmProject));
|
||||
// a hack to ensure the parent task has already been run. this will not be necessary once tests are per distribution
|
||||
// which will eliminate the copy distributions task altogether
|
||||
vmDependencies.add(copyDistributionsTask);
|
||||
vmDependencies.add(project.getConfigurations().getByName("testRuntimeClasspath"));
|
||||
|
||||
distroTests.forEach((desc, task) -> configureVMWrapperTask(vmProject, desc, task.getName(), vmDependencies));
|
||||
VagrantExtension vagrant = vmProject.getExtensions().getByType(VagrantExtension.class);
|
||||
batsTests.forEach((desc, task) -> {
|
||||
configureVMWrapperTask(vmProject, desc, task.getName(), vmDependencies).configure(t -> {
|
||||
t.setProgressHandler(new BatsProgressLogger(project.getLogger()));
|
||||
t.onlyIf(spec -> vagrant.isWindowsVM() == false); // bats doesn't run on windows
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static Jdk createJdk(NamedDomainObjectContainer<Jdk> jdksContainer, String name, String version, String platform) {
|
||||
|
@ -125,20 +140,22 @@ public class DistroTestPlugin implements Plugin<Project> {
|
|||
return indexCompatVersions.get(new Random(seed).nextInt(indexCompatVersions.size()));
|
||||
}
|
||||
|
||||
private void configureVM(Project project) {
|
||||
private static List<Object> configureVM(Project project) {
|
||||
String box = project.getName();
|
||||
|
||||
// setup jdks used by the distro tests, and by gradle executing
|
||||
|
||||
NamedDomainObjectContainer<Jdk> jdksContainer = JdkDownloadPlugin.getContainer(project);
|
||||
String platform = box.contains("windows") ? "windows" : "linux";
|
||||
this.gradleJdk = createJdk(jdksContainer, "gradle", GRADLE_JDK_VERSION, platform);
|
||||
Jdk gradleJdk = createJdk(jdksContainer, "gradle", GRADLE_JDK_VERSION, platform);
|
||||
|
||||
// setup VM used by these tests
|
||||
VagrantExtension vagrant = project.getExtensions().getByType(VagrantExtension.class);
|
||||
vagrant.setBox(box);
|
||||
vagrant.vmEnv("PATH", convertPath(project, vagrant, gradleJdk, "/bin:$PATH", "\\bin;$Env:PATH"));
|
||||
vagrant.setIsWindowsVM(box.contains("windows"));
|
||||
|
||||
return Arrays.asList(gradleJdk);
|
||||
}
|
||||
|
||||
private static Object convertPath(Project project, VagrantExtension vagrant, Jdk jdk,
|
||||
|
@ -154,10 +171,11 @@ public class DistroTestPlugin implements Plugin<Project> {
|
|||
};
|
||||
}
|
||||
|
||||
private void configureCopyPackagingTask(Project project) {
|
||||
this.archivesDir = project.getParent().getLayout().getBuildDirectory().dir("packaging/archives");
|
||||
private static TaskProvider<Copy> configureCopyDistributionsTask(Project project, Version upgradeVersion,
|
||||
Provider<Directory> archivesDir) {
|
||||
|
||||
// temporary, until we have tasks per distribution
|
||||
this.copyPackagingArchives = Boilerplate.maybeRegister(project.getParent().getTasks(), COPY_PACKAGING_TASK, Copy.class,
|
||||
return project.getTasks().register(COPY_DISTRIBUTIONS_TASK, Copy.class,
|
||||
t -> {
|
||||
t.into(archivesDir);
|
||||
t.from(project.getConfigurations().getByName(PACKAGING_DISTRIBUTION));
|
||||
|
@ -195,64 +213,50 @@ public class DistroTestPlugin implements Plugin<Project> {
|
|||
});
|
||||
}
|
||||
|
||||
private void configureDistroTest(Project project) {
|
||||
BuildPlugin.configureCompile(project);
|
||||
BuildPlugin.configureRepositories(project);
|
||||
BuildPlugin.configureTestTasks(project);
|
||||
BuildPlugin.configureInputNormalization(project);
|
||||
|
||||
TaskProvider<Test> destructiveTest = project.getTasks().register("destructiveDistroTest", Test.class,
|
||||
t -> {
|
||||
t.setMaxParallelForks(1);
|
||||
t.setWorkingDir(archivesDir.get());
|
||||
if (System.getProperty(IN_VM_SYSPROP) == null) {
|
||||
t.dependsOn(copyPackagingArchives, gradleJdk);
|
||||
}
|
||||
});
|
||||
|
||||
// setup outer task to run
|
||||
project.getTasks().register("distroTest", GradleDistroTestTask.class,
|
||||
private TaskProvider<GradleDistroTestTask> configureVMWrapperTask(Project project, String type, String destructiveTaskPath,
|
||||
List<Object> dependsOn) {
|
||||
int taskNameStart = destructiveTaskPath.lastIndexOf(':') + "destructive".length() + 1;
|
||||
String taskname = destructiveTaskPath.substring(taskNameStart);
|
||||
taskname = taskname.substring(0, 1).toLowerCase(Locale.ROOT) + taskname.substring(1);
|
||||
return project.getTasks().register(taskname, GradleDistroTestTask.class,
|
||||
t -> {
|
||||
t.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
|
||||
t.setDescription("Runs distribution tests within vagrant");
|
||||
t.setTaskName(project.getPath() + ":" + destructiveTest.getName());
|
||||
t.setDescription("Runs " + type + " tests within vagrant");
|
||||
t.setTaskName(destructiveTaskPath);
|
||||
t.extraArg("-D'" + IN_VM_SYSPROP + "'");
|
||||
t.dependsOn(copyPackagingArchives, gradleJdk);
|
||||
t.dependsOn(dependsOn);
|
||||
});
|
||||
}
|
||||
|
||||
private void configureBatsTest(Project project, String type) {
|
||||
|
||||
// destructive task to run inside
|
||||
TaskProvider<BatsTestTask> destructiveTest = project.getTasks().register("destructiveBatsTest." + type, BatsTestTask.class,
|
||||
private TaskProvider<?> configureDistroTest(Project project, Provider<Directory> distributionsDir,
|
||||
TaskProvider<Copy> copyPackagingArchives) {
|
||||
// TODO: don't run with security manager...
|
||||
return project.getTasks().register("destructiveDistroTest", Test.class,
|
||||
t -> {
|
||||
// this is hacky for shared source, but bats are a temporary thing we are removing, so it is not worth
|
||||
// the overhead of a real project dependency
|
||||
Directory batsDir = project.getParent().getLayout().getProjectDirectory().dir("bats");
|
||||
t.setTestsDir(batsDir.dir(type));
|
||||
t.setUtilsDir(batsDir.dir("utils"));
|
||||
t.setArchivesDir(archivesDir.get());
|
||||
t.setPackageName("elasticsearch" + (type.equals("oss") ? "-oss" : ""));
|
||||
t.setMaxParallelForks(1);
|
||||
t.setWorkingDir(distributionsDir);
|
||||
if (System.getProperty(IN_VM_SYSPROP) == null) {
|
||||
t.dependsOn(copyPackagingArchives, gradleJdk);
|
||||
t.dependsOn(copyPackagingArchives);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
VagrantExtension vagrant = project.getExtensions().getByType(VagrantExtension.class);
|
||||
// setup outer task to run
|
||||
project.getTasks().register("batsTest." + type, GradleDistroTestTask.class,
|
||||
private TaskProvider<?> configureBatsTest(Project project, String type, Provider<Directory> distributionsDir,
|
||||
TaskProvider<Copy> copyPackagingArchives) {
|
||||
return project.getTasks().register("destructiveBatsTest." + type, BatsTestTask.class,
|
||||
t -> {
|
||||
t.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
|
||||
t.setDescription("Runs bats tests within vagrant");
|
||||
t.setTaskName(project.getPath() + ":" + destructiveTest.getName());
|
||||
t.setProgressHandler(new BatsProgressLogger(project.getLogger()));
|
||||
t.extraArg("-D'" + IN_VM_SYSPROP + "'");
|
||||
t.dependsOn(copyPackagingArchives, gradleJdk);
|
||||
t.onlyIf(spec -> vagrant.isWindowsVM() == false); // bats doesn't run on windows
|
||||
Directory batsDir = project.getLayout().getProjectDirectory().dir("bats");
|
||||
t.setTestsDir(batsDir.dir(type));
|
||||
t.setUtilsDir(batsDir.dir("utils"));
|
||||
t.setDistributionsDir(distributionsDir);
|
||||
t.setPackageName("elasticsearch" + (type.equals("oss") ? "-oss" : ""));
|
||||
if (System.getProperty(IN_VM_SYSPROP) == null) {
|
||||
t.dependsOn(copyPackagingArchives);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void configureDistributions(Project project) {
|
||||
private void configureDistributions(Project project, Version upgradeVersion) {
|
||||
NamedDomainObjectContainer<ElasticsearchDistribution> distributions = DistributionDownloadPlugin.getContainer(project);
|
||||
|
||||
for (Type type : Arrays.asList(Type.DEB, Type.RPM)) {
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.elasticsearch.gradle.test;
|
|||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
@ -31,36 +33,42 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class BatsTestTask extends DefaultTask {
|
||||
|
||||
private Directory testsDir;
|
||||
private Directory utilsDir;
|
||||
private Directory archivesDir;
|
||||
private final DirectoryProperty testsDir;
|
||||
private final DirectoryProperty utilsDir;
|
||||
private final DirectoryProperty distributionsDir;
|
||||
private String packageName;
|
||||
|
||||
public BatsTestTask() {
|
||||
this.testsDir = getProject().getObjects().directoryProperty();
|
||||
this.utilsDir = getProject().getObjects().directoryProperty();
|
||||
this.distributionsDir = getProject().getObjects().directoryProperty();
|
||||
}
|
||||
|
||||
@InputDirectory
|
||||
public Directory getTestsDir() {
|
||||
public Provider<Directory> getTestsDir() {
|
||||
return testsDir;
|
||||
}
|
||||
|
||||
public void setTestsDir(Directory testsDir) {
|
||||
this.testsDir = testsDir;
|
||||
this.testsDir.set(testsDir);
|
||||
}
|
||||
|
||||
@InputDirectory
|
||||
public Directory getUtilsDir() {
|
||||
public Provider<Directory> getUtilsDir() {
|
||||
return utilsDir;
|
||||
}
|
||||
|
||||
public void setUtilsDir(Directory utilsDir) {
|
||||
this.utilsDir = utilsDir;
|
||||
this.utilsDir.set(utilsDir);
|
||||
}
|
||||
|
||||
@InputDirectory
|
||||
public Directory getArchivesDir() {
|
||||
return archivesDir;
|
||||
public Provider<Directory> getDistributionsDir() {
|
||||
return distributionsDir;
|
||||
}
|
||||
|
||||
public void setArchivesDir(Directory archivesDir) {
|
||||
this.archivesDir = archivesDir;
|
||||
public void setDistributionsDir(Provider<Directory> distributionsDir) {
|
||||
this.distributionsDir.set(distributionsDir);
|
||||
}
|
||||
|
||||
@Input
|
||||
|
@ -81,10 +89,10 @@ public class BatsTestTask extends DefaultTask {
|
|||
.filter(f -> f.getName().endsWith(".bats"))
|
||||
.sorted().collect(Collectors.toList()));
|
||||
getProject().exec(spec -> {
|
||||
spec.setWorkingDir(archivesDir.getAsFile());
|
||||
spec.setWorkingDir(distributionsDir.getAsFile());
|
||||
spec.environment(System.getenv());
|
||||
spec.environment("BATS_TESTS", testsDir.getAsFile().toString());
|
||||
spec.environment("BATS_UTILS", utilsDir.getAsFile().toString());
|
||||
spec.environment("BATS_TESTS", testsDir.getAsFile().get().toString());
|
||||
spec.environment("BATS_UTILS", utilsDir.getAsFile().get().toString());
|
||||
spec.environment("PACKAGE_NAME", packageName);
|
||||
spec.setCommandLine(command);
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
plugins {
|
||||
id 'elasticsearch.build'
|
||||
id 'elasticsearch.distro-test'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -35,14 +35,7 @@ dependencies {
|
|||
compile project(':libs:elasticsearch-core')
|
||||
}
|
||||
|
||||
configurations.create('testClasses')
|
||||
|
||||
String classesDir = project.file(project.sourceSets.main.output.classesDirs.singleFile).toString()
|
||||
artifacts.add('testClasses', project.layout.projectDirectory.dir(classesDir)) {
|
||||
builtBy tasks.named('testClasses')
|
||||
}
|
||||
|
||||
forbiddenApisMain {
|
||||
forbiddenApisTest {
|
||||
replaceSignatureFiles 'jdk-signatures'
|
||||
}
|
||||
|
||||
|
@ -69,24 +62,14 @@ tasks.thirdPartyAudit.ignoreMissingClasses (
|
|||
'javax.servlet.ServletContextListener'
|
||||
)
|
||||
|
||||
boolean sample = project.properties.get('vagrant.boxes') != 'all'
|
||||
tasks.register('destructivePackagingTest') {
|
||||
dependsOn 'destructiveDistroTest', 'destructiveBatsTest.oss', 'destructiveBatsTest.default'
|
||||
}
|
||||
|
||||
subprojects { Project platformProject ->
|
||||
apply plugin: 'elasticsearch.distro-test'
|
||||
apply plugin: 'java'
|
||||
|
||||
configurations.create('testClasses')
|
||||
dependencies {
|
||||
testClasses project(path: ':qa:vagrant', configuration: 'testClasses')
|
||||
testRuntime project(path: ':qa:vagrant', configuration: 'runtime')
|
||||
}
|
||||
|
||||
tasks.named('destructiveDistroTest') {
|
||||
testClassesDirs += project.files(configurations.testClasses.singleFile)
|
||||
}
|
||||
|
||||
// TODO: remove this property lookup once CI is switched to use an explicit task for the sample tests
|
||||
boolean allBoxes = project.properties.get('vagrant.boxes', '') == 'all'
|
||||
boolean allBoxes = (project.findProperty('vagrant.boxes') ?: '') == 'all'
|
||||
if (allBoxes || ['centos-7', 'ubuntu-1604'].contains(platformProject.name)) {
|
||||
tasks.register('packagingTest') {
|
||||
dependsOn 'distroTest', 'batsTest.oss', 'batsTest.default'
|
||||
|
@ -96,7 +79,6 @@ subprojects { Project platformProject ->
|
|||
vagrant {
|
||||
hostEnv 'VAGRANT_PROJECT_DIR', platformProject.projectDir.absolutePath
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
@ -115,7 +97,7 @@ for (Project subproj : project.rootProject.subprojects) {
|
|||
}
|
||||
plugins = plugins.toSorted()
|
||||
|
||||
copyPackagingArchives {
|
||||
tasks.named('copyDistributions') {
|
||||
from configurations.allPlugins
|
||||
doLast {
|
||||
// TODO: this was copied from the old way bats tests get the plugins list. we should pass
|
||||
|
|
Loading…
Reference in New Issue