Skip to content

Commit a6faf85

Browse files
authored
Migrate systemd packaging tests from bats to java backport(#39954) (#40763)
Migrating systemd bats tests from bats to java dsl. This also covers partially the sysv, but more must be added relates #32143 backport #39954
1 parent e5cec87 commit a6faf85

File tree

5 files changed

+243
-274
lines changed

5 files changed

+243
-274
lines changed

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

Lines changed: 195 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,45 @@
2020
package org.elasticsearch.packaging.test;
2121

2222
import com.carrotsearch.randomizedtesting.annotations.TestCaseOrdering;
23+
import org.apache.http.client.fluent.Request;
24+
import org.elasticsearch.packaging.util.FileUtils;
2325
import org.elasticsearch.packaging.util.Shell;
2426
import org.elasticsearch.packaging.util.Shell.Result;
27+
import org.hamcrest.CoreMatchers;
2528
import org.junit.Before;
2629

2730
import java.io.IOException;
2831
import java.nio.charset.StandardCharsets;
2932
import java.nio.file.Files;
3033
import java.nio.file.Path;
34+
import java.nio.file.Paths;
3135
import java.nio.file.StandardOpenOption;
3236
import java.util.regex.Matcher;
3337
import java.util.regex.Pattern;
3438

39+
import static org.elasticsearch.packaging.util.FileUtils.append;
3540
import static org.elasticsearch.packaging.util.FileUtils.assertPathsDontExist;
41+
import static org.elasticsearch.packaging.util.FileUtils.assertPathsExist;
42+
import static org.elasticsearch.packaging.util.FileUtils.cp;
43+
import static org.elasticsearch.packaging.util.FileUtils.fileWithGlobExist;
44+
import static org.elasticsearch.packaging.util.FileUtils.mkdir;
3645
import static org.elasticsearch.packaging.util.FileUtils.mv;
46+
import static org.elasticsearch.packaging.util.FileUtils.rm;
47+
import static org.elasticsearch.packaging.util.FileUtils.slurp;
3748
import static org.elasticsearch.packaging.util.Packages.SYSTEMD_SERVICE;
3849
import static org.elasticsearch.packaging.util.Packages.assertInstalled;
3950
import static org.elasticsearch.packaging.util.Packages.assertRemoved;
4051
import static org.elasticsearch.packaging.util.Packages.install;
4152
import static org.elasticsearch.packaging.util.Packages.remove;
53+
import static org.elasticsearch.packaging.util.Packages.restartElasticsearch;
4254
import static org.elasticsearch.packaging.util.Packages.startElasticsearch;
4355
import static org.elasticsearch.packaging.util.Packages.stopElasticsearch;
4456
import static org.elasticsearch.packaging.util.Packages.verifyPackageInstallation;
4557
import static org.elasticsearch.packaging.util.Platforms.getOsRelease;
4658
import static org.elasticsearch.packaging.util.Platforms.isSystemd;
59+
import static org.elasticsearch.packaging.util.ServerUtils.makeRequest;
4760
import static org.elasticsearch.packaging.util.ServerUtils.runElasticsearchTests;
61+
import static org.hamcrest.CoreMatchers.equalTo;
4862
import static org.hamcrest.CoreMatchers.not;
4963
import static org.hamcrest.CoreMatchers.notNullValue;
5064
import static org.hamcrest.Matchers.containsString;
@@ -55,42 +69,50 @@
5569

5670
@TestCaseOrdering(TestCaseOrdering.AlphabeticOrder.class)
5771
public abstract class PackageTestCase extends PackagingTestCase {
72+
private Shell sh;
5873

5974
@Before
6075
public void onlyCompatibleDistributions() {
6176
assumeTrue("only compatible distributions", distribution().packaging.compatible);
77+
sh = newShell();
6278
}
6379

6480
public void test10InstallPackage() throws IOException {
6581
assertRemoved(distribution());
6682
installation = install(distribution());
6783
assertInstalled(distribution());
68-
verifyPackageInstallation(installation, distribution(), newShell());
84+
verifyPackageInstallation(installation, distribution(), sh);
6985
}
7086

7187
public void test20PluginsCommandWhenNoPlugins() {
7288
assumeThat(installation, is(notNullValue()));
7389

74-
assertThat(newShell().run(installation.bin("elasticsearch-plugin") + " list").stdout, isEmptyString());
90+
assertThat(sh.run(installation.bin("elasticsearch-plugin") + " list").stdout, isEmptyString());
7591
}
7692

77-
public void test30InstallDoesNotStartServer() {
93+
public void test30DaemonIsNotEnabledOnRestart() {
94+
if (isSystemd()) {
95+
sh.run("systemctl daemon-reload");
96+
String isEnabledOutput = sh.runIgnoreExitCode("systemctl is-enabled elasticsearch.service").stdout.trim();
97+
assertThat(isEnabledOutput, equalTo("disabled"));
98+
}
99+
}
100+
101+
public void test31InstallDoesNotStartServer() {
78102
assumeThat(installation, is(notNullValue()));
79103

80-
assertThat(newShell().run("ps aux").stdout, not(containsString("org.elasticsearch.bootstrap.Elasticsearch")));
104+
assertThat(sh.run("ps aux").stdout, not(containsString("org.elasticsearch.bootstrap.Elasticsearch")));
81105
}
82106

83107
public void assertRunsWithJavaHome() throws IOException {
84-
Shell sh = newShell();
85-
86108
String systemJavaHome = sh.run("echo $SYSTEM_JAVA_HOME").stdout.trim();
87109
byte[] originalEnvFile = Files.readAllBytes(installation.envFile);
88110
try {
89111
Files.write(installation.envFile, ("JAVA_HOME=" + systemJavaHome + "\n").getBytes(StandardCharsets.UTF_8),
90112
StandardOpenOption.APPEND);
91-
startElasticsearch();
113+
startElasticsearch(sh);
92114
runElasticsearchTests();
93-
stopElasticsearch();
115+
stopElasticsearch(sh);
94116
} finally {
95117
Files.write(installation.envFile, originalEnvFile);
96118
}
@@ -99,7 +121,7 @@ public void assertRunsWithJavaHome() throws IOException {
99121
assertThat(new String(Files.readAllBytes(log), StandardCharsets.UTF_8), containsString(systemJavaHome));
100122
}
101123

102-
public void test31JavaHomeOverride() throws IOException {
124+
public void test32JavaHomeOverride() throws IOException {
103125
assumeThat(installation, is(notNullValue()));
104126
// we always run with java home when no bundled jdk is included, so this test would be repetitive
105127
assumeThat(distribution().hasJdk, is(true));
@@ -121,11 +143,21 @@ public void test42BundledJdkRemoved() throws IOException {
121143
}
122144

123145
public void test40StartServer() throws IOException {
146+
String start = sh.runIgnoreExitCode("date ").stdout.trim();
124147
assumeThat(installation, is(notNullValue()));
125148

126-
startElasticsearch();
149+
startElasticsearch(sh);
150+
151+
String journalEntries = sh.runIgnoreExitCode("journalctl _SYSTEMD_UNIT=elasticsearch.service " +
152+
"--since \"" + start + "\" --output cat | grep -v \"future versions of Elasticsearch will require Java 11\" | wc -l")
153+
.stdout.trim();
154+
assertThat(journalEntries, equalTo("0"));
155+
156+
assertPathsExist(installation.pidDir.resolve("elasticsearch.pid"));
157+
assertPathsExist(installation.logs.resolve("elasticsearch_server.json"));
158+
127159
runElasticsearchTests();
128-
verifyPackageInstallation(installation, distribution(), newShell()); // check startup script didn't change permissions
160+
verifyPackageInstallation(installation, distribution(), sh); // check startup script didn't change permissions
129161
}
130162

131163
public void test50Remove() {
@@ -134,7 +166,6 @@ public void test50Remove() {
134166
remove(distribution());
135167

136168
// removing must stop the service
137-
final Shell sh = newShell();
138169
assertThat(sh.run("ps aux").stdout, not(containsString("org.elasticsearch.bootstrap.Elasticsearch")));
139170

140171
if (isSystemd()) {
@@ -184,9 +215,160 @@ public void test60Reinstall() throws IOException {
184215

185216
installation = install(distribution());
186217
assertInstalled(distribution());
187-
verifyPackageInstallation(installation, distribution(), newShell());
218+
verifyPackageInstallation(installation, distribution(), sh);
188219

189220
remove(distribution());
190221
assertRemoved(distribution());
191222
}
223+
224+
public void test70RestartServer() throws IOException {
225+
try {
226+
installation = install(distribution());
227+
assertInstalled(distribution());
228+
229+
startElasticsearch(sh);
230+
restartElasticsearch(sh);
231+
runElasticsearchTests();
232+
stopElasticsearch(sh);
233+
} finally {
234+
cleanup();
235+
}
236+
}
237+
238+
239+
public void test72TestRuntimeDirectory() throws IOException {
240+
try {
241+
installation = install(distribution());
242+
FileUtils.rm(installation.pidDir);
243+
startElasticsearch(sh);
244+
assertPathsExist(installation.pidDir);
245+
stopElasticsearch(sh);
246+
} finally {
247+
cleanup();
248+
}
249+
}
250+
251+
public void test73gcLogsExist() throws IOException {
252+
installation = install(distribution());
253+
startElasticsearch(sh);
254+
// it can be gc.log or gc.log.0.current
255+
assertThat(installation.logs, fileWithGlobExist("gc.log*"));
256+
stopElasticsearch(sh);
257+
}
258+
259+
// TEST CASES FOR SYSTEMD ONLY
260+
261+
262+
/**
263+
* # Simulates the behavior of a system restart:
264+
* # the PID directory is deleted by the operating system
265+
* # but it should not block ES from starting
266+
* # see https://github.com/elastic/elasticsearch/issues/11594
267+
*/
268+
public void test80DeletePID_DIRandRestart() throws IOException {
269+
assumeTrue(isSystemd());
270+
271+
rm(installation.pidDir);
272+
273+
sh.run("systemd-tmpfiles --create");
274+
275+
startElasticsearch(sh);
276+
277+
final Path pidFile = installation.pidDir.resolve("elasticsearch.pid");
278+
279+
assertTrue(Files.exists(pidFile));
280+
281+
stopElasticsearch(sh);
282+
}
283+
284+
public void test81CustomPathConfAndJvmOptions() throws IOException {
285+
assumeTrue(isSystemd());
286+
287+
assumeThat(installation, is(notNullValue()));
288+
assertPathsExist(installation.envFile);
289+
290+
stopElasticsearch(sh);
291+
292+
// The custom config directory is not under /tmp or /var/tmp because
293+
// systemd's private temp directory functionally means different
294+
// processes can have different views of what's in these directories
295+
String temp = sh.runIgnoreExitCode("mktemp -p /etc -d").stdout.trim();
296+
final Path tempConf = Paths.get(temp);
297+
298+
try {
299+
mkdir(tempConf);
300+
cp(installation.config("elasticsearch.yml"), tempConf.resolve("elasticsearch.yml"));
301+
cp(installation.config("log4j2.properties"), tempConf.resolve("log4j2.properties"));
302+
303+
// we have to disable Log4j from using JMX lest it will hit a security
304+
// manager exception before we have configured logging; this will fail
305+
// startup since we detect usages of logging before it is configured
306+
final String jvmOptions =
307+
"-Xms512m\n" +
308+
"-Xmx512m\n" +
309+
"-Dlog4j2.disable.jmx=true\n";
310+
append(tempConf.resolve("jvm.options"), jvmOptions);
311+
312+
sh.runIgnoreExitCode("chown -R elasticsearch:elasticsearch " + tempConf);
313+
314+
final Shell serverShell = newShell();
315+
cp(installation.envFile, tempConf.resolve("elasticsearch.bk"));//backup
316+
append(installation.envFile, "ES_PATH_CONF=" + tempConf + "\n");
317+
append(installation.envFile, "ES_JAVA_OPTS=-XX:-UseCompressedOops");
318+
319+
startElasticsearch(serverShell);
320+
321+
final String nodesResponse = makeRequest(Request.Get("http://localhost:9200/_nodes"));
322+
assertThat(nodesResponse, CoreMatchers.containsString("\"heap_init_in_bytes\":536870912"));
323+
assertThat(nodesResponse, CoreMatchers.containsString("\"using_compressed_ordinary_object_pointers\":\"false\""));
324+
325+
stopElasticsearch(serverShell);
326+
327+
} finally {
328+
rm(installation.envFile);
329+
cp(tempConf.resolve("elasticsearch.bk"), installation.envFile);
330+
rm(tempConf);
331+
cleanup();
332+
}
333+
}
334+
335+
public void test82SystemdMask() throws IOException {
336+
try {
337+
assumeTrue(isSystemd());
338+
339+
sh.run("systemctl mask systemd-sysctl.service");
340+
341+
installation = install(distribution());
342+
343+
sh.run("systemctl unmask systemd-sysctl.service");
344+
} finally {
345+
cleanup();
346+
}
347+
}
348+
349+
public void test83serviceFileSetsLimits() throws IOException {
350+
// Limits are changed on systemd platforms only
351+
assumeTrue(isSystemd());
352+
353+
installation = install(distribution());
354+
355+
startElasticsearch(sh);
356+
357+
final Path pidFile = installation.pidDir.resolve("elasticsearch.pid");
358+
assertTrue(Files.exists(pidFile));
359+
String pid = slurp(pidFile).trim();
360+
String maxFileSize = sh.run("cat /proc/%s/limits | grep \"Max file size\" | awk '{ print $4 }'", pid).stdout.trim();
361+
assertThat(maxFileSize, equalTo("unlimited"));
362+
363+
String maxProcesses = sh.run("cat /proc/%s/limits | grep \"Max processes\" | awk '{ print $3 }'", pid).stdout.trim();
364+
assertThat(maxProcesses, equalTo("4096"));
365+
366+
String maxOpenFiles = sh.run("cat /proc/%s/limits | grep \"Max open files\" | awk '{ print $4 }'", pid).stdout.trim();
367+
assertThat(maxOpenFiles, equalTo("65535"));
368+
369+
String maxAddressSpace = sh.run("cat /proc/%s/limits | grep \"Max address space\" | awk '{ print $4 }'", pid).stdout.trim();
370+
assertThat(maxAddressSpace, equalTo("unlimited"));
371+
372+
stopElasticsearch(sh);
373+
}
192374
}

qa/vagrant/src/main/java/org/elasticsearch/packaging/util/FileUtils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
package org.elasticsearch.packaging.util;
2121

2222
import org.elasticsearch.core.internal.io.IOUtils;
23+
import org.hamcrest.FeatureMatcher;
24+
import org.hamcrest.Matcher;
2325

2426
import java.io.BufferedWriter;
2527
import java.io.IOException;
@@ -34,9 +36,11 @@
3436
import java.nio.file.attribute.PosixFileAttributes;
3537
import java.util.ArrayList;
3638
import java.util.Arrays;
39+
import java.util.Collections;
3740
import java.util.List;
3841

3942
import static org.hamcrest.MatcherAssert.assertThat;
43+
import static org.hamcrest.Matchers.emptyIterable;
4044
import static org.hamcrest.core.IsNot.not;
4145
import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString;
4246
import static org.junit.Assert.assertFalse;
@@ -69,6 +73,15 @@ public static void rm(Path... paths) {
6973
}
7074
}
7175

76+
public static Path mktempDir(Path path) {
77+
try {
78+
return Files.createTempDirectory(path,"tmp");
79+
} catch (IOException e) {
80+
throw new RuntimeException(e);
81+
}
82+
}
83+
84+
7285
public static Path mkdir(Path path) {
7386
try {
7487
return Files.createDirectories(path);
@@ -176,6 +189,20 @@ public static void assertPathsExist(Path... paths) {
176189
Arrays.stream(paths).forEach(path -> assertTrue(path + " should exist", Files.exists(path)));
177190
}
178191

192+
public static Matcher<Path> fileWithGlobExist(String glob) throws IOException {
193+
return new FeatureMatcher<Path,Iterable<Path>>(not(emptyIterable()),"File with pattern exist", "file with pattern"){
194+
195+
@Override
196+
protected Iterable<Path> featureValueOf(Path actual) {
197+
try {
198+
return Files.newDirectoryStream(actual,glob);
199+
} catch (IOException e) {
200+
return Collections.emptyList();
201+
}
202+
}
203+
};
204+
}
205+
179206
public static void assertPathsDontExist(Path... paths) {
180207
Arrays.stream(paths).forEach(path -> assertFalse(path + " should not exist", Files.exists(path)));
181208
}

0 commit comments

Comments
 (0)