Skip to content

Commit 006c2c9

Browse files
[test] port archive distribution packaging tests (#31314)
Recreates the rest of the bats packaging tests for the tar distribution in the java packaging test project, with support for both tar and zip packaging, both oss and default flavors, and on Linux and Windows. Most tests are followed fairly closely, some have either been dropped if unnecessary or folded into others if convenient.
1 parent 8ec33b7 commit 006c2c9

File tree

11 files changed

+675
-299
lines changed

11 files changed

+675
-299
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/vagrant/VagrantTestPlugin.groovy

+8-2
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,15 @@ class VagrantTestPlugin implements Plugin<Project> {
546546
javaPackagingTest.command = 'ssh'
547547
javaPackagingTest.args = ['--command', 'sudo bash "$PACKAGING_TESTS/run-tests.sh"']
548548
} else {
549+
// powershell sessions run over winrm always run as administrator, whether --elevated is passed or not. however
550+
// remote sessions have some restrictions on what they can do, such as impersonating another user (or the same user
551+
// without administrator elevation), which we need to do for these tests. passing --elevated runs the session
552+
// as a scheduled job locally on the vm as a true administrator to get around this limitation
553+
//
554+
// https://github.com/hashicorp/vagrant/blob/9c299a2a357fcf87f356bb9d56e18a037a53d138/plugins/communicators/winrm/communicator.rb#L195-L225
555+
// https://devops-collective-inc.gitbooks.io/secrets-of-powershell-remoting/content/manuscript/accessing-remote-computers.html
549556
javaPackagingTest.command = 'winrm'
550-
// winrm commands run as administrator
551-
javaPackagingTest.args = ['--command', 'powershell -File "$Env:PACKAGING_TESTS/run-tests.ps1"']
557+
javaPackagingTest.args = ['--elevated', '--command', 'powershell -File "$Env:PACKAGING_TESTS/run-tests.ps1"']
552558
}
553559

554560
TaskExecutionAdapter javaPackagingReproListener = createReproListener(project, javaPackagingTest.path)

qa/vagrant/build.gradle

+20
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ dependencies {
3131
compile "org.hamcrest:hamcrest-core:${versions.hamcrest}"
3232
compile "org.hamcrest:hamcrest-library:${versions.hamcrest}"
3333

34+
compile "org.apache.httpcomponents:httpcore:${versions.httpcore}"
35+
compile "org.apache.httpcomponents:httpclient:${versions.httpclient}"
36+
compile "org.apache.httpcomponents:fluent-hc:${versions.httpclient}"
37+
compile "commons-codec:commons-codec:${versions.commonscodec}"
38+
compile "commons-logging:commons-logging:${versions.commonslogging}"
39+
3440
compile project(':libs:core')
3541

3642
// pulls in the jar built by this project and its dependencies
@@ -73,3 +79,17 @@ tasks.test.enabled = false
7379
// this project doesn't get published
7480
tasks.dependencyLicenses.enabled = false
7581
tasks.dependenciesInfo.enabled = false
82+
83+
tasks.thirdPartyAudit.excludes = [
84+
//commons-logging optional dependencies
85+
'org.apache.avalon.framework.logger.Logger',
86+
'org.apache.log.Hierarchy',
87+
'org.apache.log.Logger',
88+
'org.apache.log4j.Category',
89+
'org.apache.log4j.Level',
90+
'org.apache.log4j.Logger',
91+
'org.apache.log4j.Priority',
92+
//commons-logging provided dependencies
93+
'javax.servlet.ServletContextEvent',
94+
'javax.servlet.ServletContextListener'
95+
]

qa/vagrant/src/main/java/org/elasticsearch/packaging/test/ArchiveTestCase.java

+252
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919

2020
package org.elasticsearch.packaging.test;
2121

22+
import org.apache.http.client.fluent.Request;
23+
import org.elasticsearch.packaging.util.Archives;
24+
import org.elasticsearch.packaging.util.Platforms;
25+
import org.elasticsearch.packaging.util.ServerUtils;
26+
import org.elasticsearch.packaging.util.Shell;
27+
import org.elasticsearch.packaging.util.Shell.Result;
2228
import org.junit.Before;
2329
import org.junit.BeforeClass;
2430
import org.junit.FixMethodOrder;
@@ -28,9 +34,33 @@
2834
import org.elasticsearch.packaging.util.Distribution;
2935
import org.elasticsearch.packaging.util.Installation;
3036

37+
import java.io.IOException;
38+
import java.nio.file.Files;
39+
import java.nio.file.Path;
40+
import java.util.Arrays;
41+
import java.util.stream.Stream;
42+
43+
import static java.util.stream.Collectors.joining;
44+
import static org.elasticsearch.packaging.util.Archives.ARCHIVE_OWNER;
3145
import static org.elasticsearch.packaging.util.Cleanup.cleanEverything;
3246
import static org.elasticsearch.packaging.util.Archives.installArchive;
3347
import static org.elasticsearch.packaging.util.Archives.verifyArchiveInstallation;
48+
import static org.elasticsearch.packaging.util.FileMatcher.Fileness.File;
49+
import static org.elasticsearch.packaging.util.FileMatcher.file;
50+
import static org.elasticsearch.packaging.util.FileMatcher.p660;
51+
import static org.elasticsearch.packaging.util.FileUtils.append;
52+
import static org.elasticsearch.packaging.util.FileUtils.cp;
53+
import static org.elasticsearch.packaging.util.FileUtils.getTempDir;
54+
import static org.elasticsearch.packaging.util.FileUtils.mkdir;
55+
import static org.elasticsearch.packaging.util.FileUtils.rm;
56+
import static org.elasticsearch.packaging.util.ServerUtils.makeRequest;
57+
import static org.hamcrest.CoreMatchers.containsString;
58+
import static org.hamcrest.CoreMatchers.is;
59+
import static org.hamcrest.CoreMatchers.notNullValue;
60+
import static org.hamcrest.MatcherAssert.assertThat;
61+
import static org.hamcrest.Matchers.isEmptyString;
62+
import static org.junit.Assert.assertTrue;
63+
import static org.junit.Assume.assumeThat;
3464
import static org.junit.Assume.assumeTrue;
3565

3666
/**
@@ -61,4 +91,226 @@ public void test10Install() {
6191
installation = installArchive(distribution());
6292
verifyArchiveInstallation(installation, distribution());
6393
}
94+
95+
@Test
96+
public void test20PluginsListWithNoPlugins() {
97+
assumeThat(installation, is(notNullValue()));
98+
99+
final Installation.Executables bin = installation.executables();
100+
final Shell sh = new Shell();
101+
final Result r = sh.run(bin.elasticsearchPlugin + " list");
102+
103+
assertThat(r.stdout, isEmptyString());
104+
}
105+
106+
@Test
107+
public void test30AbortWhenJavaMissing() {
108+
assumeThat(installation, is(notNullValue()));
109+
110+
final Installation.Executables bin = installation.executables();
111+
final Shell sh = new Shell();
112+
113+
Platforms.onWindows(() -> {
114+
// on windows, removing java from PATH and removing JAVA_HOME is less involved than changing the permissions of the java
115+
// executable. we also don't check permissions in the windows scripts anyway
116+
final String originalPath = sh.run("$Env:PATH").stdout.trim();
117+
final String newPath = Arrays.stream(originalPath.split(";"))
118+
.filter(path -> path.contains("Java") == false)
119+
.collect(joining(";"));
120+
121+
// note the lack of a $ when clearing the JAVA_HOME env variable - with a $ it deletes the java home directory
122+
// https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/providers/environment-provider?view=powershell-6
123+
//
124+
// this won't persist to another session so we don't have to reset anything
125+
final Result runResult = sh.runIgnoreExitCode(
126+
"$Env:PATH = '" + newPath + "'; " +
127+
"Remove-Item Env:JAVA_HOME; " +
128+
bin.elasticsearch
129+
);
130+
131+
assertThat(runResult.exitCode, is(1));
132+
assertThat(runResult.stderr, containsString("could not find java; set JAVA_HOME or ensure java is in PATH"));
133+
});
134+
135+
Platforms.onLinux(() -> {
136+
final String javaPath = sh.run("which java").stdout.trim();
137+
138+
try {
139+
sh.run("chmod -x '" + javaPath + "'");
140+
final Result runResult = sh.runIgnoreExitCode(bin.elasticsearch.toString());
141+
assertThat(runResult.exitCode, is(1));
142+
assertThat(runResult.stdout, containsString("could not find java; set JAVA_HOME or ensure java is in PATH"));
143+
} finally {
144+
sh.run("chmod +x '" + javaPath + "'");
145+
}
146+
});
147+
}
148+
149+
@Test
150+
public void test40CreateKeystoreManually() {
151+
assumeThat(installation, is(notNullValue()));
152+
153+
final Installation.Executables bin = installation.executables();
154+
final Shell sh = new Shell();
155+
156+
Platforms.onLinux(() -> sh.run("sudo -u " + ARCHIVE_OWNER + " " + bin.elasticsearchKeystore + " create"));
157+
158+
// this is a hack around the fact that we can't run a command in the same session as the same user but not as administrator.
159+
// the keystore ends up being owned by the Administrators group, so we manually set it to be owned by the vagrant user here.
160+
// from the server's perspective the permissions aren't really different, this is just to reflect what we'd expect in the tests.
161+
// when we run these commands as a role user we won't have to do this
162+
Platforms.onWindows(() -> sh.run(
163+
bin.elasticsearchKeystore + " create; " +
164+
"$account = New-Object System.Security.Principal.NTAccount 'vagrant'; " +
165+
"$acl = Get-Acl '" + installation.config("elasticsearch.keystore") + "'; " +
166+
"$acl.SetOwner($account); " +
167+
"Set-Acl '" + installation.config("elasticsearch.keystore") + "' $acl"
168+
));
169+
170+
assertThat(installation.config("elasticsearch.keystore"), file(File, ARCHIVE_OWNER, ARCHIVE_OWNER, p660));
171+
172+
Platforms.onLinux(() -> {
173+
final Result r = sh.run("sudo -u " + ARCHIVE_OWNER + " " + bin.elasticsearchKeystore + " list");
174+
assertThat(r.stdout, containsString("keystore.seed"));
175+
});
176+
177+
Platforms.onWindows(() -> {
178+
final Result r = sh.run(bin.elasticsearchKeystore + " list");
179+
assertThat(r.stdout, containsString("keystore.seed"));
180+
});
181+
}
182+
183+
@Test
184+
public void test50StartAndStop() throws IOException {
185+
assumeThat(installation, is(notNullValue()));
186+
187+
// cleanup from previous test
188+
rm(installation.config("elasticsearch.keystore"));
189+
190+
Archives.runElasticsearch(installation);
191+
192+
final String gcLogName = Platforms.LINUX
193+
? "gc.log.0.current"
194+
: "gc.log";
195+
assertTrue("gc logs exist", Files.exists(installation.logs.resolve(gcLogName)));
196+
ServerUtils.runElasticsearchTests();
197+
198+
Archives.stopElasticsearch(installation);
199+
}
200+
201+
@Test
202+
public void test60AutoCreateKeystore() {
203+
assumeThat(installation, is(notNullValue()));
204+
205+
assertThat(installation.config("elasticsearch.keystore"), file(File, ARCHIVE_OWNER, ARCHIVE_OWNER, p660));
206+
207+
final Installation.Executables bin = installation.executables();
208+
final Shell sh = new Shell();
209+
210+
Platforms.onLinux(() -> {
211+
final Result result = sh.run("sudo -u " + ARCHIVE_OWNER + " " + bin.elasticsearchKeystore + " list");
212+
assertThat(result.stdout, containsString("keystore.seed"));
213+
});
214+
215+
Platforms.onWindows(() -> {
216+
final Result result = sh.run(bin.elasticsearchKeystore + " list");
217+
assertThat(result.stdout, containsString("keystore.seed"));
218+
});
219+
}
220+
221+
@Test
222+
public void test70CustomPathConfAndJvmOptions() throws IOException {
223+
assumeThat(installation, is(notNullValue()));
224+
225+
final Path tempConf = getTempDir().resolve("esconf-alternate");
226+
227+
try {
228+
mkdir(tempConf);
229+
cp(installation.config("elasticsearch.yml"), tempConf.resolve("elasticsearch.yml"));
230+
cp(installation.config("log4j2.properties"), tempConf.resolve("log4j2.properties"));
231+
232+
// we have to disable Log4j from using JMX lest it will hit a security
233+
// manager exception before we have configured logging; this will fail
234+
// startup since we detect usages of logging before it is configured
235+
final String jvmOptions =
236+
"-Xms512m\n" +
237+
"-Xmx512m\n" +
238+
"-Dlog4j2.disable.jmx=true\n";
239+
append(tempConf.resolve("jvm.options"), jvmOptions);
240+
241+
final Shell sh = new Shell();
242+
Platforms.onLinux(() -> sh.run("chown -R elasticsearch:elasticsearch " + tempConf));
243+
Platforms.onWindows(() -> sh.run(
244+
"$account = New-Object System.Security.Principal.NTAccount 'vagrant'; " +
245+
"$tempConf = Get-ChildItem '" + tempConf + "' -Recurse; " +
246+
"$tempConf += Get-Item '" + tempConf + "'; " +
247+
"$tempConf | ForEach-Object { " +
248+
"$acl = Get-Acl $_.FullName; " +
249+
"$acl.SetOwner($account); " +
250+
"Set-Acl $_.FullName $acl " +
251+
"}"
252+
));
253+
254+
final Shell serverShell = new Shell();
255+
serverShell.getEnv().put("ES_PATH_CONF", tempConf.toString());
256+
serverShell.getEnv().put("ES_JAVA_OPTS", "-XX:-UseCompressedOops");
257+
258+
Archives.runElasticsearch(installation, serverShell);
259+
260+
final String nodesResponse = makeRequest(Request.Get("http://localhost:9200/_nodes"));
261+
assertThat(nodesResponse, containsString("\"heap_init_in_bytes\":536870912"));
262+
assertThat(nodesResponse, containsString("\"using_compressed_ordinary_object_pointers\":\"false\""));
263+
264+
Archives.stopElasticsearch(installation);
265+
266+
} finally {
267+
rm(tempConf);
268+
}
269+
}
270+
271+
@Test
272+
public void test80RelativePathConf() throws IOException {
273+
assumeThat(installation, is(notNullValue()));
274+
275+
final Path temp = getTempDir().resolve("esconf-alternate");
276+
final Path tempConf = temp.resolve("config");
277+
278+
try {
279+
mkdir(tempConf);
280+
Stream.of(
281+
"elasticsearch.yml",
282+
"log4j2.properties",
283+
"jvm.options"
284+
).forEach(file -> cp(installation.config(file), tempConf.resolve(file)));
285+
286+
append(tempConf.resolve("elasticsearch.yml"), "node.name: relative");
287+
288+
final Shell sh = new Shell();
289+
Platforms.onLinux(() -> sh.run("chown -R elasticsearch:elasticsearch " + temp));
290+
Platforms.onWindows(() -> sh.run(
291+
"$account = New-Object System.Security.Principal.NTAccount 'vagrant'; " +
292+
"$tempConf = Get-ChildItem '" + temp + "' -Recurse; " +
293+
"$tempConf += Get-Item '" + temp + "'; " +
294+
"$tempConf | ForEach-Object { " +
295+
"$acl = Get-Acl $_.FullName; " +
296+
"$acl.SetOwner($account); " +
297+
"Set-Acl $_.FullName $acl " +
298+
"}"
299+
));
300+
301+
final Shell serverShell = new Shell(temp);
302+
serverShell.getEnv().put("ES_PATH_CONF", "config");
303+
Archives.runElasticsearch(installation, serverShell);
304+
305+
final String nodesResponse = makeRequest(Request.Get("http://localhost:9200/_nodes"));
306+
assertThat(nodesResponse, containsString("\"name\":\"relative\""));
307+
308+
Archives.stopElasticsearch(installation);
309+
310+
} finally {
311+
rm(tempConf);
312+
}
313+
}
314+
315+
64316
}

0 commit comments

Comments
 (0)