Skip to content

Commit ccb3e22

Browse files
authored
Simplify adding plugins and modules to testclusters (#61886)
There are currently half a dozen ways to add plugins and modules for test clusters to use. All of them require the calling project to peek into the plugin or module they want to use to grab its bundlePlugin task, and then both depend on that task, as well as extract the archive path the task will produce. This creates cross project dependencies that are difficult to detect, and if the dependent plugin/module has not yet been configured, the build will fail because the task does not yet exist. This commit makes the plugin and module methods for testclusters symmetetric, and simply adding a file provider directly, or a project path that will produce the plugin/module zip. Internally this new variant uses normal configuration/dependencies across projects to get the zip artifact. It also has the added benefit of no longer needing the caller to add to the test task a dependsOn for bundlePlugin task.
1 parent 511babd commit ccb3e22

File tree

21 files changed

+72
-112
lines changed

21 files changed

+72
-112
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import org.elasticsearch.gradle.info.BuildParams
2828
import org.elasticsearch.gradle.test.RestIntegTestTask
2929
import org.elasticsearch.gradle.test.RestTestBasePlugin
3030
import org.elasticsearch.gradle.testclusters.RunTask
31-
import org.elasticsearch.gradle.testclusters.TestClustersPlugin
3231
import org.elasticsearch.gradle.util.Util
3332
import org.gradle.api.InvalidUserDataException
3433
import org.gradle.api.Plugin
@@ -42,9 +41,6 @@ import org.gradle.api.tasks.SourceSet
4241
import org.gradle.api.tasks.TaskProvider
4342
import org.gradle.api.tasks.bundling.Zip
4443

45-
import java.util.regex.Matcher
46-
import java.util.regex.Pattern
47-
4844
/**
4945
* Encapsulates build configuration for an Elasticsearch plugin.
5046
*/
@@ -79,10 +75,9 @@ class PluginBuildPlugin implements Plugin<Project> {
7975
project.extensions.getByType(PluginPropertiesExtension).extendedPlugins.each { pluginName ->
8076
// Auto add dependent modules to the test cluster
8177
if (project.findProject(":modules:${pluginName}") != null) {
82-
project.integTest.dependsOn(project.project(":modules:${pluginName}").tasks.bundlePlugin)
83-
project.testClusters.integTest.module(
84-
project.project(":modules:${pluginName}").tasks.bundlePlugin.archiveFile
85-
)
78+
project.testClusters.all {
79+
module(":modules:${pluginName}")
80+
}
8681
}
8782
}
8883
PluginPropertiesExtension extension1 = project.getExtensions().getByType(PluginPropertiesExtension.class)

buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchCluster.java

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.gradle.api.NamedDomainObjectContainer;
2727
import org.gradle.api.Project;
2828
import org.gradle.api.file.RegularFile;
29-
import org.gradle.api.file.RegularFileProperty;
3029
import org.gradle.api.logging.Logger;
3130
import org.gradle.api.logging.Logging;
3231
import org.gradle.api.provider.Provider;
@@ -36,7 +35,6 @@
3635
import java.io.File;
3736
import java.io.IOException;
3837
import java.io.UncheckedIOException;
39-
import java.net.URI;
4038
import java.nio.charset.StandardCharsets;
4139
import java.nio.file.Files;
4240
import java.security.GeneralSecurityException;
@@ -135,33 +133,23 @@ public void setTestDistribution(TestDistribution distribution) {
135133
}
136134

137135
@Override
138-
public void plugin(URI plugin) {
136+
public void plugin(Provider<RegularFile> plugin) {
139137
nodes.all(each -> each.plugin(plugin));
140138
}
141139

142140
@Override
143-
public void plugin(File plugin) {
144-
nodes.all(each -> each.plugin(plugin));
145-
}
146-
147-
@Override
148-
public void plugin(Provider<URI> plugin) {
149-
nodes.all(each -> each.plugin(plugin));
150-
}
151-
152-
@Override
153-
public void plugin(RegularFileProperty plugin) {
154-
nodes.all(each -> each.plugin(plugin));
141+
public void plugin(String pluginProjectPath) {
142+
nodes.all(each -> each.plugin(pluginProjectPath));
155143
}
156144

157145
@Override
158-
public void module(File module) {
146+
public void module(Provider<RegularFile> module) {
159147
nodes.all(each -> each.module(module));
160148
}
161149

162150
@Override
163-
public void module(Provider<RegularFile> module) {
164-
nodes.all(each -> each.module(module));
151+
public void module(String moduleProjectPath) {
152+
nodes.all(each -> each.module(moduleProjectPath));
165153
}
166154

167155
@Override

buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java

Lines changed: 36 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,11 @@
3737
import org.gradle.api.Named;
3838
import org.gradle.api.NamedDomainObjectContainer;
3939
import org.gradle.api.Project;
40+
import org.gradle.api.artifacts.Configuration;
4041
import org.gradle.api.file.FileTree;
4142
import org.gradle.api.file.RegularFile;
42-
import org.gradle.api.file.RegularFileProperty;
4343
import org.gradle.api.logging.Logger;
4444
import org.gradle.api.logging.Logging;
45-
import org.gradle.api.provider.Property;
4645
import org.gradle.api.provider.Provider;
4746
import org.gradle.api.tasks.Classpath;
4847
import org.gradle.api.tasks.Input;
@@ -61,7 +60,6 @@
6160
import java.io.InputStream;
6261
import java.io.LineNumberReader;
6362
import java.io.UncheckedIOException;
64-
import java.net.URI;
6563
import java.nio.charset.StandardCharsets;
6664
import java.nio.file.Files;
6765
import java.nio.file.Path;
@@ -70,6 +68,7 @@
7068
import java.time.Instant;
7169
import java.util.ArrayList;
7270
import java.util.Arrays;
71+
import java.util.Collection;
7372
import java.util.Collections;
7473
import java.util.Comparator;
7574
import java.util.HashMap;
@@ -126,7 +125,8 @@ public class ElasticsearchNode implements TestClusterConfiguration {
126125
private final Path workingDir;
127126

128127
private final LinkedHashMap<String, Predicate<TestClusterConfiguration>> waitConditions = new LinkedHashMap<>();
129-
private final List<Provider<URI>> plugins = new ArrayList<>();
128+
private final Map<String, Configuration> pluginAndModuleConfigurations = new HashMap<>();
129+
private final List<Provider<File>> plugins = new ArrayList<>();
130130
private final List<Provider<File>> modules = new ArrayList<>();
131131
private final LazyPropertyMap<String, CharSequence> settings = new LazyPropertyMap<>("Settings", this);
132132
private final LazyPropertyMap<String, CharSequence> keystoreSettings = new LazyPropertyMap<>("Keystore", this);
@@ -262,45 +262,50 @@ private void setDistributionType(ElasticsearchDistribution distribution, TestDis
262262
}
263263
}
264264

265-
@Override
266-
public void plugin(RegularFileProperty plugin) {
267-
this.plugins.add(plugin.map(p -> p.getAsFile().toURI()));
265+
// package protected so only TestClustersAware can access
266+
@Internal
267+
Collection<Configuration> getPluginAndModuleConfigurations() {
268+
return pluginAndModuleConfigurations.values();
268269
}
269270

270-
@Override
271-
public void plugin(Provider<URI> plugin) {
272-
requireNonNull(plugin, "Plugin name can't be null");
273-
checkFrozen();
274-
if (plugins.contains(plugin)) {
275-
throw new TestClustersException("Plugin already configured for installation " + plugin);
276-
}
277-
this.plugins.add(plugin);
271+
// creates a configuration to depend on the given plugin project, then wraps that configuration
272+
// to grab the zip as a file provider
273+
private Provider<RegularFile> maybeCreatePluginOrModuleDependency(String path) {
274+
Configuration configuration = pluginAndModuleConfigurations.computeIfAbsent(
275+
path,
276+
key -> project.getConfigurations()
277+
.detachedConfiguration(project.getDependencies().project(Map.of("path", path, "configuration", "zip")))
278+
);
279+
Provider<File> fileProvider = configuration.getElements()
280+
.map(
281+
s -> s.stream()
282+
.findFirst()
283+
.orElseThrow(() -> new IllegalStateException("zip configuration of project " + path + " had no files"))
284+
.getAsFile()
285+
);
286+
return project.getLayout().file(fileProvider);
278287
}
279288

280289
@Override
281-
public void plugin(URI plugin) {
282-
Property<URI> uri = project.getObjects().property(URI.class);
283-
uri.set(plugin);
284-
this.plugin(uri);
290+
public void plugin(Provider<RegularFile> plugin) {
291+
checkFrozen();
292+
this.plugins.add(plugin.map(RegularFile::getAsFile));
285293
}
286294

287295
@Override
288-
public void plugin(File plugin) {
289-
Property<URI> uri = project.getObjects().property(URI.class);
290-
uri.set(plugin.toURI());
291-
this.plugin(uri);
296+
public void plugin(String pluginProjectPath) {
297+
plugin(maybeCreatePluginOrModuleDependency(pluginProjectPath));
292298
}
293299

294300
@Override
295-
public void module(File module) {
296-
RegularFileProperty file = project.getObjects().fileProperty();
297-
file.fileValue(module);
298-
this.module(file);
301+
public void module(Provider<RegularFile> module) {
302+
checkFrozen();
303+
this.modules.add(module.map(RegularFile::getAsFile));
299304
}
300305

301306
@Override
302-
public void module(Provider<RegularFile> module) {
303-
this.modules.add(module.map(RegularFile::getAsFile));
307+
public void module(String moduleProjectPath) {
308+
module(maybeCreatePluginOrModuleDependency(moduleProjectPath));
304309
}
305310

306311
@Override
@@ -449,7 +454,7 @@ public synchronized void start() {
449454
logToProcessStdout("installing " + plugins.size() + " plugins in a single transaction");
450455
final String[] arguments = Stream.concat(
451456
Stream.of("install", "--batch"),
452-
plugins.stream().map(Provider::get).map(URI::toString)
457+
plugins.stream().map(Provider::get).map(p -> p.toURI().toString())
453458
).toArray(String[]::new);
454459
runElasticsearchBinScript("elasticsearch-plugin", arguments);
455460
} else {
@@ -1242,10 +1247,7 @@ private Path getExtractedDistributionDir() {
12421247
}
12431248

12441249
private List<File> getInstalledFileSet(Action<? super PatternFilterable> filter) {
1245-
return Stream.concat(
1246-
plugins.stream().map(Provider::get).filter(uri -> uri.getScheme().equalsIgnoreCase("file")).map(File::new),
1247-
modules.stream().map(p -> p.get())
1248-
)
1250+
return Stream.concat(plugins.stream().map(Provider::get), modules.stream().map(Provider::get))
12491251
.filter(File::exists)
12501252
// TODO: We may be able to simplify this with Gradle 5.6
12511253
// https://docs.gradle.org/nightly/release-notes.html#improved-handling-of-zip-archives-on-classpaths
@@ -1255,15 +1257,6 @@ private List<File> getInstalledFileSet(Action<? super PatternFilterable> filter)
12551257
.collect(Collectors.toList());
12561258
}
12571259

1258-
@Input
1259-
public Set<URI> getRemotePlugins() {
1260-
Set<URI> file = plugins.stream()
1261-
.map(Provider::get)
1262-
.filter(uri -> uri.getScheme().equalsIgnoreCase("file") == false)
1263-
.collect(Collectors.toSet());
1264-
return file;
1265-
}
1266-
12671260
@Classpath
12681261
public List<File> getInstalledClasspath() {
12691262
return getInstalledFileSet(filter -> filter.include("**/*.jar"));

buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClusterConfiguration.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@
2121
import org.elasticsearch.gradle.FileSupplier;
2222
import org.elasticsearch.gradle.PropertyNormalization;
2323
import org.gradle.api.file.RegularFile;
24-
import org.gradle.api.file.RegularFileProperty;
2524
import org.gradle.api.logging.Logging;
2625
import org.gradle.api.provider.Provider;
2726
import org.slf4j.Logger;
2827

2928
import java.io.File;
30-
import java.net.URI;
3129
import java.util.LinkedHashMap;
3230
import java.util.List;
3331
import java.util.Locale;
@@ -45,18 +43,14 @@ public interface TestClusterConfiguration {
4543

4644
void setTestDistribution(TestDistribution distribution);
4745

48-
void plugin(URI plugin);
46+
void plugin(Provider<RegularFile> plugin);
4947

50-
void plugin(File plugin);
51-
52-
void plugin(Provider<URI> plugin);
53-
54-
void plugin(RegularFileProperty plugin);
55-
56-
void module(File module);
48+
void plugin(String pluginProjectPath);
5749

5850
void module(Provider<RegularFile> module);
5951

52+
void module(String moduleProjectPath);
53+
6054
void keystore(String key, String value);
6155

6256
void keystore(String key, Supplier<CharSequence> valueSupplier);

buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersAware.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
package org.elasticsearch.gradle.testclusters;
2020

2121
import org.gradle.api.Task;
22+
import org.gradle.api.artifacts.Configuration;
2223
import org.gradle.api.tasks.Nested;
2324

2425
import java.util.Collection;
26+
import java.util.concurrent.Callable;
2527

2628
public interface TestClustersAware extends Task {
2729

@@ -34,6 +36,7 @@ default void useCluster(ElasticsearchCluster cluster) {
3436
}
3537

3638
cluster.getNodes().stream().flatMap(node -> node.getDistributions().stream()).forEach(distro -> dependsOn(distro.getExtracted()));
39+
cluster.getNodes().forEach(node -> dependsOn((Callable<Collection<Configuration>>) node::getPluginAndModuleConfigurations));
3740
getClusters().add(cluster);
3841
}
3942

docs/build.gradle

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,7 @@ project.rootProject.subprojects.findAll { it.parent.path == ':plugins' }.each {
9494
if (subproj.path.startsWith(':plugins:ingest-attachment') && BuildParams.inFipsJvm) {
9595
return
9696
}
97-
// FIXME
98-
subproj.afterEvaluate { // need to wait until the project has been configured
99-
testClusters.integTest {
100-
plugin subproj.bundlePlugin.archiveFile
101-
}
102-
tasks.integTest.dependsOn subproj.bundlePlugin
103-
}
97+
testClusters.integTest.plugin subproj.path
10498
}
10599

106100
buildRestTests.docs = fileTree(projectDir) {

modules/ingest-common/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ restResources {
4040
testClusters.all {
4141
// Needed in order to test ingest pipeline templating:
4242
// (this is because the integTest node is not using default distribution, but only the minimal number of required modules)
43-
module project(':modules:lang-mustache').tasks.bundlePlugin.archiveFile
43+
module ':modules:lang-mustache'
4444
}
4545

4646
thirdPartyAudit.ignoreMissingClasses(

modules/kibana/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ dependencies {
2828
}
2929

3030
testClusters.all {
31-
module file(project(':modules:reindex').tasks.bundlePlugin.archiveFile)
31+
module ':modules:reindex'
3232
}
3333

modules/lang-painless/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ esplugin {
2727
}
2828

2929
testClusters.all {
30-
module project(':modules:mapper-extras').tasks.bundlePlugin.archiveFile
30+
module ':modules:mapper-extras'
3131
systemProperty 'es.scripting.update.ctx_in_params', 'false'
3232
// TODO: remove this once cname is prepended to transport.publish_address by default in 8.0
3333
systemProperty 'es.transport.cname_in_publish_address', 'true'

modules/rank-eval/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@ restResources {
3232

3333
testClusters.all {
3434
// Modules who's integration is explicitly tested in integration tests
35-
module project(':modules:lang-mustache').tasks.bundlePlugin.archiveFile
35+
module ':modules:lang-mustache'
3636
}

0 commit comments

Comments
 (0)