Skip to content

Commit e916b17

Browse files
authored
Allow overriding of plugin metadata files in integration tests (#120245) (#120297)
1 parent 70d0621 commit e916b17

File tree

7 files changed

+190
-11
lines changed

7 files changed

+190
-11
lines changed

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.elasticsearch.test.cluster.local.distribution.DistributionResolver;
2020
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
2121
import org.elasticsearch.test.cluster.local.model.User;
22+
import org.elasticsearch.test.cluster.util.ArchivePatcher;
2223
import org.elasticsearch.test.cluster.util.IOUtils;
2324
import org.elasticsearch.test.cluster.util.OS;
2425
import org.elasticsearch.test.cluster.util.Pair;
@@ -649,27 +650,56 @@ private void installPlugins() {
649650
.toList();
650651

651652
List<String> toInstall = spec.getPlugins()
653+
.entrySet()
652654
.stream()
653655
.map(
654-
pluginName -> pluginPaths.stream()
656+
plugin -> pluginPaths.stream()
655657
.map(path -> Pair.of(pattern.matcher(path.getFileName().toString()), path))
656-
.filter(pair -> pair.left.matches() && pair.left.group(1).equals(pluginName))
658+
.filter(pair -> pair.left.matches() && pair.left.group(1).equals(plugin.getKey()))
657659
.map(p -> p.right.getParent().resolve(p.left.group(0)))
658660
.findFirst()
661+
.map(path -> {
662+
DefaultPluginInstallSpec installSpec = plugin.getValue();
663+
// Path the plugin archive with configured overrides if necessary
664+
if (installSpec.entitlementsOverride != null || installSpec.propertiesOverride != null) {
665+
Path target;
666+
try {
667+
target = Files.createTempFile("patched-", path.getFileName().toString());
668+
} catch (IOException e) {
669+
throw new UncheckedIOException("Failed to create temporary file", e);
670+
}
671+
ArchivePatcher patcher = new ArchivePatcher(path, target);
672+
if (installSpec.entitlementsOverride != null) {
673+
patcher.override(
674+
"entitlement-policy.yaml",
675+
original -> installSpec.entitlementsOverride.apply(original).asStream()
676+
);
677+
}
678+
if (installSpec.propertiesOverride != null) {
679+
patcher.override(
680+
"plugin-descriptor.properties",
681+
original -> installSpec.propertiesOverride.apply(original).asStream()
682+
);
683+
}
684+
return patcher.patch();
685+
} else {
686+
return path;
687+
}
688+
})
659689
.orElseThrow(() -> {
660690
String taskPath = System.getProperty("tests.task");
661691
String project = taskPath.substring(0, taskPath.lastIndexOf(':'));
662692

663-
throw new RuntimeException(
693+
return new RuntimeException(
664694
"Unable to locate plugin '"
665-
+ pluginName
695+
+ plugin.getKey()
666696
+ "'. Ensure you've added the following to the build script for project '"
667697
+ project
668698
+ "':\n\n"
669699
+ "dependencies {\n"
670700
+ " clusterPlugins "
671701
+ "project(':plugins:"
672-
+ pluginName
702+
+ plugin.getKey()
673703
+ "')"
674704
+ "\n}"
675705
);

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.List;
2525
import java.util.Map;
2626
import java.util.Set;
27+
import java.util.function.Consumer;
2728
import java.util.function.Predicate;
2829
import java.util.function.Supplier;
2930

@@ -34,7 +35,7 @@ public abstract class AbstractLocalSpecBuilder<T extends LocalSpecBuilder<?>> im
3435
private final List<EnvironmentProvider> environmentProviders = new ArrayList<>();
3536
private final Map<String, String> environment = new HashMap<>();
3637
private final Set<String> modules = new HashSet<>();
37-
private final Set<String> plugins = new HashSet<>();
38+
private final Map<String, DefaultPluginInstallSpec> plugins = new HashMap<>();
3839
private final Set<FeatureFlag> features = EnumSet.noneOf(FeatureFlag.class);
3940
private final List<SettingsProvider> keystoreProviders = new ArrayList<>();
4041
private final Map<String, String> keystoreSettings = new HashMap<>();
@@ -132,11 +133,19 @@ Set<String> getModules() {
132133

133134
@Override
134135
public T plugin(String pluginName) {
135-
this.plugins.add(pluginName);
136+
this.plugins.put(pluginName, new DefaultPluginInstallSpec());
136137
return cast(this);
137138
}
138139

139-
Set<String> getPlugins() {
140+
@Override
141+
public T plugin(String pluginName, Consumer<? super PluginInstallSpec> config) {
142+
DefaultPluginInstallSpec spec = new DefaultPluginInstallSpec();
143+
config.accept(spec);
144+
this.plugins.put(pluginName, spec);
145+
return cast(this);
146+
}
147+
148+
Map<String, DefaultPluginInstallSpec> getPlugins() {
140149
return inherit(() -> parent.getPlugins(), plugins);
141150
}
142151

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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.test.cluster.local;
11+
12+
import org.elasticsearch.test.cluster.util.resource.Resource;
13+
14+
import java.util.function.Function;
15+
16+
public class DefaultPluginInstallSpec implements PluginInstallSpec {
17+
Function<? super String, ? extends Resource> propertiesOverride;
18+
Function<? super String, ? extends Resource> entitlementsOverride;
19+
20+
@Override
21+
public PluginInstallSpec withPropertiesOverride(Function<? super String, ? extends Resource> override) {
22+
this.propertiesOverride = override;
23+
return this;
24+
}
25+
26+
@Override
27+
public PluginInstallSpec withEntitlementsOverride(Function<? super String, ? extends Resource> override) {
28+
this.entitlementsOverride = override;
29+
return this;
30+
}
31+
}

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public static class LocalNodeSpec {
9292
private final List<EnvironmentProvider> environmentProviders;
9393
private final Map<String, String> environment;
9494
private final Set<String> modules;
95-
private final Set<String> plugins;
95+
private final Map<String, DefaultPluginInstallSpec> plugins;
9696
private final DistributionType distributionType;
9797
private final Set<FeatureFlag> features;
9898
private final List<SettingsProvider> keystoreProviders;
@@ -114,7 +114,7 @@ public LocalNodeSpec(
114114
List<EnvironmentProvider> environmentProviders,
115115
Map<String, String> environment,
116116
Set<String> modules,
117-
Set<String> plugins,
117+
Map<String, DefaultPluginInstallSpec> plugins,
118118
DistributionType distributionType,
119119
Set<FeatureFlag> features,
120120
List<SettingsProvider> keystoreProviders,
@@ -179,7 +179,7 @@ public Set<String> getModules() {
179179
return modules;
180180
}
181181

182-
public Set<String> getPlugins() {
182+
public Map<String, DefaultPluginInstallSpec> getPlugins() {
183183
return plugins;
184184
}
185185

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.elasticsearch.test.cluster.util.Version;
1919
import org.elasticsearch.test.cluster.util.resource.Resource;
2020

21+
import java.util.function.Consumer;
2122
import java.util.function.Predicate;
2223
import java.util.function.Supplier;
2324

@@ -73,6 +74,11 @@ interface LocalSpecBuilder<T extends LocalSpecBuilder<?>> {
7374
*/
7475
T plugin(String pluginName);
7576

77+
/**
78+
* Ensure plugin is installed into the distribution.
79+
*/
80+
T plugin(String pluginName, Consumer<? super PluginInstallSpec> config);
81+
7682
/**
7783
* Require feature to be enabled in the cluster.
7884
*/
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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.test.cluster.local;
11+
12+
import org.elasticsearch.test.cluster.util.resource.Resource;
13+
14+
import java.util.function.Function;
15+
16+
public interface PluginInstallSpec {
17+
18+
/**
19+
* Override bundled plugin properties file with the given {@link Resource}. The provided override function receives the original
20+
* file content as function argument.
21+
*
22+
* @param override function returning resource used to override bundled properties file
23+
*/
24+
PluginInstallSpec withPropertiesOverride(Function<? super String, ? extends Resource> override);
25+
26+
/**
27+
* Override bundled entitlements policy file with the given {@link Resource}. The provided override function receives the original
28+
* file content as function argument.
29+
*
30+
* @param override function returning resource used to override bundled entitlements policy file
31+
*/
32+
PluginInstallSpec withEntitlementsOverride(Function<? super String, ? extends Resource> override);
33+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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.test.cluster.util;
11+
12+
import java.io.BufferedOutputStream;
13+
import java.io.BufferedReader;
14+
import java.io.FileOutputStream;
15+
import java.io.IOException;
16+
import java.io.InputStream;
17+
import java.io.InputStreamReader;
18+
import java.io.UncheckedIOException;
19+
import java.nio.file.Path;
20+
import java.util.Enumeration;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
import java.util.function.Function;
24+
import java.util.stream.Collectors;
25+
import java.util.zip.ZipEntry;
26+
import java.util.zip.ZipFile;
27+
import java.util.zip.ZipOutputStream;
28+
29+
public class ArchivePatcher {
30+
private final Path original;
31+
private final Path target;
32+
private final Map<String, Function<? super String, ? extends InputStream>> overrides = new HashMap<>();
33+
34+
public ArchivePatcher(Path original, Path target) {
35+
this.original = original;
36+
this.target = target;
37+
}
38+
39+
public void override(String filename, Function<? super String, ? extends InputStream> override) {
40+
this.overrides.put(filename, override);
41+
}
42+
43+
public Path patch() {
44+
try (
45+
ZipFile input = new ZipFile(original.toFile());
46+
ZipOutputStream output = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(target.toFile())))
47+
) {
48+
Enumeration<? extends ZipEntry> entries = input.entries();
49+
while (entries.hasMoreElements()) {
50+
ZipEntry entry = entries.nextElement();
51+
output.putNextEntry(entry);
52+
if (overrides.containsKey(entry.getName())) {
53+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input.getInputStream(entry)))) {
54+
String content = reader.lines().collect(Collectors.joining(System.lineSeparator()));
55+
overrides.get(entry.getName()).apply(content).transferTo(output);
56+
}
57+
} else {
58+
input.getInputStream(entry).transferTo(output);
59+
}
60+
output.closeEntry();
61+
}
62+
output.flush();
63+
output.finish();
64+
} catch (IOException e) {
65+
throw new UncheckedIOException("Failed to patch archive", e);
66+
}
67+
68+
return target;
69+
}
70+
}

0 commit comments

Comments
 (0)