Skip to content

Commit ca0117d

Browse files
committed
Simplifying testcluster wiring;adding integtests
1 parent 2dd9270 commit ca0117d

File tree

73 files changed

+331
-127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+331
-127
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.gradle.internal
11+
12+
import org.elasticsearch.gradle.VersionProperties
13+
import org.elasticsearch.gradle.fixtures.AbstractGradleFuncTest
14+
import org.elasticsearch.gradle.plugin.BasePluginBuildPlugin
15+
import org.gradle.testkit.runner.TaskOutcome
16+
import java.nio.file.Files
17+
import java.nio.file.Path
18+
import java.util.stream.Collectors
19+
20+
class BaseInternalPluginBuildPluginFuncTest extends AbstractGradleFuncTest {
21+
22+
def "can assemble plugin via #taskName"() {
23+
given:
24+
buildFile << """plugins {
25+
id 'elasticsearch.base-internal-es-plugin'
26+
}
27+
28+
esplugin {
29+
description = 'test plugin'
30+
classname = 'com.acme.plugin.TestPlugin'
31+
}
32+
33+
// for testing purposes only
34+
configurations.compileOnly.dependencies.clear()
35+
"""
36+
37+
when:
38+
def result = gradleRunner(taskName).build()
39+
40+
then:
41+
result.task(taskName).outcome == TaskOutcome.SUCCESS
42+
file(expectedOutputPath).exists()
43+
44+
where:
45+
expectedOutputPath | taskName
46+
"build/distributions/hello-world.zip" | ":bundlePlugin"
47+
"build/explodedBundle/" | ":explodedBundlePlugin"
48+
}
49+
50+
def "can resolve plugin as directory without intermediate zipping "() {
51+
given:
52+
buildFile << """plugins {
53+
id 'elasticsearch.base-internal-es-plugin'
54+
}
55+
56+
esplugin {
57+
name = 'sample-plugin'
58+
description = 'test plugin'
59+
classname = 'com.acme.plugin.TestPlugin'
60+
}
61+
62+
// for testing purposes only
63+
configurations.compileOnly.dependencies.clear()
64+
"""
65+
66+
file('settings.gradle') << "include 'module-consumer'"
67+
file('module-consumer/build.gradle') << """
68+
configurations {
69+
consume
70+
}
71+
72+
dependencies {
73+
consume project(path:':', configuration:'${BasePluginBuildPlugin.EXPLODED_BUNDLE_CONFIG}')
74+
}
75+
76+
tasks.register("resolveModule", Copy) {
77+
from configurations.consume
78+
into "build/resolved"
79+
}
80+
"""
81+
when:
82+
def result = gradleRunner(":module-consumer:resolveModule").build()
83+
84+
then:
85+
result.task(":module-consumer:resolveModule").outcome == TaskOutcome.SUCCESS
86+
result.task(":explodedBundlePlugin").outcome == TaskOutcome.SUCCESS
87+
file("module-consumer/build/resolved/sample-plugin.jar").exists()
88+
file("module-consumer/build/resolved/plugin-descriptor.properties").exists()
89+
}
90+
91+
def "can build plugin properties"() {
92+
given:
93+
buildFile << """plugins {
94+
id 'elasticsearch.base-internal-es-plugin'
95+
}
96+
97+
version = '1.2.3'
98+
99+
esplugin {
100+
name = 'myplugin'
101+
description = 'test plugin'
102+
classname = 'com.acme.plugin.TestPlugin'
103+
}
104+
"""
105+
106+
107+
when:
108+
def result = gradleRunner(":pluginProperties").build()
109+
def props = getPluginProperties()
110+
111+
then:
112+
result.task(":pluginProperties").outcome == TaskOutcome.SUCCESS
113+
props.get("name") == "myplugin"
114+
props.get("version") == "1.2.3"
115+
props.get("description") == "test plugin"
116+
props.get("classname") == "com.acme.plugin.TestPlugin"
117+
props.get("java.version") == Integer.toString(Runtime.version().feature())
118+
props.get("elasticsearch.version") == VersionProperties.elasticsearchVersion.toString()
119+
120+
props.get("has.native.controller") == null
121+
props.get("extended.plugins") == null
122+
props.get("modulename") == null
123+
props.size() == 6
124+
}
125+
126+
def "module name is inferred by plugin properties"() {
127+
given:
128+
buildFile << """plugins {
129+
id 'elasticsearch.base-internal-es-plugin'
130+
}
131+
132+
esplugin {
133+
name = 'myplugin'
134+
description = 'test plugin'
135+
classname = 'com.acme.plugin.TestPlugin'
136+
}
137+
138+
// for testing purposes only
139+
configurations.compileOnly.dependencies.clear()
140+
"""
141+
file('src/main/java/module-info.java') << """
142+
module org.test.plugin {
143+
}
144+
"""
145+
146+
when:
147+
def result = gradleRunner(":pluginProperties").build()
148+
def props = getPluginProperties()
149+
150+
then:
151+
result.task(":pluginProperties").outcome == TaskOutcome.SUCCESS
152+
props.get("modulename") == "org.test.plugin"
153+
}
154+
155+
def "plugin can extend internal plugin projects"() {
156+
given:
157+
subProject(":plugins:some-extendable-plugin") << """
158+
apply plugin: 'elasticsearch.internal-es-plugin'
159+
esplugin {
160+
name = 'some-extendable-plugin'
161+
description = 'extendable plugin'
162+
classname = 'com.acme.plugin.ExtendablePlugin'
163+
}
164+
"""
165+
166+
buildFile << """plugins {
167+
id 'elasticsearch.base-internal-es-plugin'
168+
}
169+
170+
esplugin {
171+
description = 'test plugin'
172+
classname = 'com.acme.plugin.TestPlugin'
173+
extendedPluginProjects {
174+
"some-extendable-plugin" {
175+
path = ':plugins:some-extendable-plugin'
176+
}
177+
}
178+
}
179+
180+
// for testing purposes only
181+
configurations.compileOnly.dependencies.clear()
182+
"""
183+
184+
when:
185+
gradleRunner(":bundlePlugin").build()
186+
then:
187+
getPluginProperties()["extended.plugins"] == "some-extendable-plugin"
188+
}
189+
190+
def "declaring extended internal plugin projects via extendedPlugins is not supported"() {
191+
given:
192+
subProject(":plugins:some-extendable-plugin") << """
193+
apply plugin: 'elasticsearch.internal-es-plugin'
194+
esplugin {
195+
name = 'some-extendable-plugin'
196+
description = 'extendable plugin'
197+
classname = 'com.acme.plugin.ExtendablePlugin'
198+
}
199+
"""
200+
201+
buildFile << """plugins {
202+
id 'elasticsearch.base-internal-es-plugin'
203+
}
204+
205+
esplugin {
206+
description = 'test plugin'
207+
classname = 'com.acme.plugin.TestPlugin'
208+
extendedPlugins = ['some-extendable-plugin']
209+
}
210+
211+
// for testing purposes only
212+
configurations.compileOnly.dependencies.clear()
213+
"""
214+
215+
when:
216+
def result = gradleRunner(":bundlePlugin").buildAndFail()
217+
218+
then:
219+
result.output.contains("Using `extendedPlugins` is not supported for internal plugins. Use `extendedPluginProjects` instead.")
220+
}
221+
222+
Map<String, String> getPluginProperties() {
223+
Path propsFile = file("build/generated-descriptor/plugin-descriptor.properties").toPath();
224+
Properties rawProps = new Properties()
225+
try (var inputStream = Files.newInputStream(propsFile)) {
226+
rawProps.load(inputStream)
227+
}
228+
return rawProps.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue().toString()))
229+
}
230+
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/BaseInternalPluginBuildPlugin.java

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.gradle.api.Plugin;
2828
import org.gradle.api.Project;
2929

30-
import java.util.HashMap;
3130
import java.util.Optional;
3231

3332
/**
@@ -50,24 +49,16 @@ public void apply(Project project) {
5049
project.getConfigurations().getByName("compileOnly").getDependencies().clear();
5150
project.getConfigurations().getByName("testImplementation").getDependencies().clear();
5251
var extension = project.getExtensions().getByType(PluginPropertiesExtension.class);
53-
5452
extension.getExtendedPluginsContainer().whenObjectAdded((Action<Named>) named -> {
5553
if (ExtendedPluginInternal.class.isAssignableFrom(named.getClass()) == false) {
5654
throw new GradleException(
5755
"Using `extendedPlugins` is not supported for internal plugins. Use `extendedPluginProjects` instead."
5856
);
5957
}
6058
});
61-
NamedDomainObjectContainer<ExtendedPluginInternal> container = project.container(
62-
ExtendedPluginInternal.class,
63-
name -> new ExtendedPluginInternal(name)
64-
);
65-
container.whenObjectAdded(
66-
internal -> extension.getExtendedPluginsContainer().add(internal)
67-
);
68-
69-
HashMap<String, String> value = new HashMap<>();
70-
extension.getExtensions().add("extendedPluginProjects", container);
59+
var extendedPluginInternalContainer = project.container(ExtendedPluginInternal.class, name -> new ExtendedPluginInternal(name));
60+
extendedPluginInternalContainer.whenObjectAdded(internal -> extension.getExtendedPluginsContainer().add(internal));
61+
extension.getExtensions().add("extendedPluginProjects", extendedPluginInternalContainer);
7162
// We've ported this from multiple build scripts where we see this pattern into
7263
// an extension method as a first step of consolidation.
7364
// We might want to port this into a general pattern later on.
@@ -102,32 +93,16 @@ public void doCall() {
10293
if (isModule == false || isXPackModule) {
10394
addNoticeGeneration(project, extension);
10495
}
105-
project.afterEvaluate(p -> {
106-
@SuppressWarnings("unchecked")
107-
NamedDomainObjectContainer<ElasticsearchCluster> testClusters = (NamedDomainObjectContainer<ElasticsearchCluster>) project
108-
.getExtensions()
109-
.getByName(TestClustersPlugin.EXTENSION_NAME);
110-
extension.getExtendedPlugins().forEach(pluginName -> {
111-
// Auto add any dependent modules
112-
findModulePath(project, pluginName).ifPresent(path -> {
113-
System.out.println("module name:" + pluginName + " path: '" + path + "'");
114-
testClusters.configureEach(elasticsearchCluster -> elasticsearchCluster.module(path));
115-
});
116-
});
96+
@SuppressWarnings("unchecked")
97+
NamedDomainObjectContainer<ElasticsearchCluster> testClusters = (NamedDomainObjectContainer<ElasticsearchCluster>) project
98+
.getExtensions()
99+
.getByName(TestClustersPlugin.EXTENSION_NAME);
100+
extendedPluginInternalContainer.all(extendedPlugin -> {
101+
// Auto add any dependent modules
102+
testClusters.configureEach(elasticsearchCluster -> elasticsearchCluster.module(extendedPlugin.path));
117103
});
118104
}
119105

120-
Optional<String> findModulePath(Project project, String pluginName) {
121-
return project.getRootProject()
122-
.getAllprojects()
123-
.stream()
124-
.filter(p -> GradleUtils.isModuleProject(p.getPath()))
125-
.filter(p -> p.getPlugins().hasPlugin(PluginBuildPlugin.class))
126-
.filter(p -> p.getExtensions().getByType(PluginPropertiesExtension.class).getName().equals(pluginName))
127-
.findFirst()
128-
.map(Project::getPath);
129-
}
130-
131106
/**
132107
* Configure the pom for the main jar of this plugin
133108
*/
@@ -153,18 +128,18 @@ protected static void addNoticeGeneration(final Project project, PluginPropertie
153128
}
154129

155130
public static class ExtendedPluginInternal extends PluginPropertiesExtension.ExtendedPlugin {
156-
String projectPath;
131+
String path;
157132

158133
public ExtendedPluginInternal(String name) {
159134
super(name);
160135
}
161136

162-
public String getProjectPath() {
163-
return projectPath;
137+
public String getPath() {
138+
return path;
164139
}
165140

166-
public void setProjectPath(String projectPath) {
167-
this.projectPath = projectPath;
141+
public void setPath(String path) {
142+
this.path = path;
168143
}
169144
}
170145
}

build-tools/src/main/java/org/elasticsearch/gradle/plugin/PluginPropertiesExtension.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.gradle.api.plugins.ExtraPropertiesExtension;
2020

2121
import java.io.File;
22-
import java.util.ArrayList;
2322
import java.util.List;
2423

2524
/**
@@ -172,10 +171,10 @@ public CopySpec getBundleSpec() {
172171
return bundleSpec;
173172
}
174173

175-
176174
public static class ExtendedPlugin implements Named {
177175

178176
private final String name;
177+
179178
public ExtendedPlugin(String name) {
180179
this.name = name;
181180
}

libs/entitlement/qa/entitlement-test-plugin/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ esplugin {
1919
classname = 'org.elasticsearch.entitlement.qa.test.EntitlementTestPlugin'
2020
extendedPluginProjects {
2121
entitled {
22-
projectPath = ':libs:entitlement:qa:entitled-plugin'
22+
path = ':libs:entitlement:qa:entitled-plugin'
2323
}
2424
}
2525
}

modules/aggregations/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ esplugin {
1515
classname ='org.elasticsearch.aggregations.AggregationsPlugin'
1616
extendedPluginProjects {
1717
"lang-painless" {
18-
projectPath = ':modules:lang-painless'
18+
path = ':modules:lang-painless'
1919
}
2020
}
2121
}

modules/analysis-common/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ esplugin {
1717
classname = 'org.elasticsearch.analysis.common.CommonAnalysisPlugin'
1818
extendedPluginProjects {
1919
"lang-painless" {
20-
projectPath = ':modules:lang-painless'
20+
path = ':modules:lang-painless'
2121
}
2222
}
2323
}

modules/ingest-common/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ esplugin {
1717
classname ='org.elasticsearch.ingest.common.IngestCommonPlugin'
1818
extendedPluginProjects {
1919
"lang-painless" {
20-
projectPath = ':modules:lang-painless'
20+
path = ':modules:lang-painless'
2121
}
2222
}
2323
}

modules/runtime-fields-common/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ esplugin {
1616
classname = 'org.elasticsearch.runtimefields.RuntimeFieldsCommonPlugin'
1717
extendedPluginProjects {
1818
"lang-painless" {
19-
projectPath = ':modules:lang-painless'
19+
path = ':modules:lang-painless'
2020
}
2121
}
2222
}

0 commit comments

Comments
 (0)