Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

package org.elasticsearch.qa.die_with_dignity;

import org.apache.lucene.util.LuceneTestCase;
import org.elasticsearch.client.Request;
import org.elasticsearch.core.PathUtils;
import org.elasticsearch.test.rest.ESRestTestCase;
Expand All @@ -17,49 +16,32 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;

@LuceneTestCase.AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/77282")
public class DieWithDignityIT extends ESRestTestCase {

public void testDieWithDignity() throws Exception {
// there should be an Elasticsearch process running with the die.with.dignity.test system property
{
final String jpsPath = PathUtils.get(System.getProperty("runtime.java.home"), "bin/jps").toString();
final Process process = new ProcessBuilder().command(jpsPath, "-v").start();

boolean found = false;
try (InputStream is = process.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
String line;
while ((line = in.readLine()) != null) {
if (line.contains("-Ddie.with.dignity.test=true")) {
found = true;
break;
}
}
}
assertTrue(found);
final Map<String, String> jvmCommandLines = getJvmCommandLines();
final boolean found = jvmCommandLines.values().stream().anyMatch(line -> line.contains("-Ddie.with.dignity.test=true"));
assertTrue(String.join(",", jvmCommandLines.values()), found);
}

expectThrows(IOException.class, () -> client().performRequest(new Request("GET", "/_die_with_dignity")));

// the Elasticsearch process should die and disappear from the output of jps
assertBusy(() -> {
final String jpsPath = PathUtils.get(System.getProperty("runtime.java.home"), "bin/jps").toString();
final Process process = new ProcessBuilder().command(jpsPath, "-v").start();

try (InputStream is = process.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
String line;
while ((line = in.readLine()) != null) {
assertThat(line, line, not(containsString("-Ddie.with.dignity.test=true")));
}
}
final Map<String, String> jvmCommandLines = getJvmCommandLines();
final boolean notFound = jvmCommandLines.values().stream().noneMatch(line -> line.contains("-Ddie.with.dignity.test=true"));
assertTrue(String.join(",", jvmCommandLines.values()), notFound);
});

// parse the logs and ensure that Elasticsearch died with the expected cause
Expand Down Expand Up @@ -95,6 +77,44 @@ public void testDieWithDignity() throws Exception {
}
}

private Map<String, String> getJvmCommandLines() throws IOException {
/*
* jps will truncate the command line to 1024 characters; so we collect the pids and then run jcmd <pid> VM.command_line to get the
* full command line.
*/
final String jpsPath = PathUtils.get(System.getProperty("runtime.java.home"), "bin/jps").toString();
final Process process = new ProcessBuilder().command(jpsPath, "-v").start();

final List<String> pids = new ArrayList<>();
try (
InputStream is = process.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))
) {
String line;
while ((line = in.readLine()) != null) {
pids.add(line.substring(0, line.indexOf(' ')));
}
}

final String jcmdPath = PathUtils.get(System.getProperty("runtime.java.home"), "bin/jcmd").toString();
final Map<String, String> jvmCommandLines = new HashMap<>();
for (final String pid : pids) {
final Process jcmdProcess = new ProcessBuilder().command(jcmdPath, pid, "VM.command_line").start();
try (
InputStream is = jcmdProcess.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))
) {
String line;
while ((line = in.readLine()) != null) {
if (line.startsWith("jvm_args")) {
jvmCommandLines.put(pid, line);
}
}
}
}
return jvmCommandLines;
}

private boolean containsAll(String line, String... subStrings) {
for (String subString : subStrings) {
if (line.matches(subString) == false) {
Expand Down