Test: Allow CliTool to write out stacktraces
In order to have the possibility of debugging on the command line, the user now can either set the es.cli.debug system property which results in stack traces being written to to the terminal. Closes #7222
This commit is contained in:
parent
9e6868733c
commit
e689a0ad71
|
@ -144,13 +144,13 @@ public abstract class CliTool {
|
||||||
return command.execute(settings, env).status;
|
return command.execute(settings, env).status;
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
terminal.printError(ioe.getMessage());
|
terminal.printError(ioe);
|
||||||
return ExitStatus.IO_ERROR.status;
|
return ExitStatus.IO_ERROR.status;
|
||||||
} catch (IllegalArgumentException | ElasticsearchIllegalArgumentException ilae) {
|
} catch (IllegalArgumentException | ElasticsearchIllegalArgumentException ilae) {
|
||||||
terminal.printError(ilae.getMessage());
|
terminal.printError(ilae);
|
||||||
return ExitStatus.USAGE.status;
|
return ExitStatus.USAGE.status;
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
terminal.printError(t.getMessage());
|
terminal.printError(t);
|
||||||
if (command == null) {
|
if (command == null) {
|
||||||
return ExitStatus.USAGE.status;
|
return ExitStatus.USAGE.status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ import java.util.Locale;
|
||||||
*/
|
*/
|
||||||
public abstract class Terminal {
|
public abstract class Terminal {
|
||||||
|
|
||||||
|
public static final String DEBUG_SYSTEM_PROPERTY = "es.cli.debug";
|
||||||
|
|
||||||
public static final Terminal DEFAULT = ConsoleTerminal.supported() ? new ConsoleTerminal() : new SystemTerminal();
|
public static final Terminal DEFAULT = ConsoleTerminal.supported() ? new ConsoleTerminal() : new SystemTerminal();
|
||||||
|
|
||||||
public static enum Verbosity {
|
public static enum Verbosity {
|
||||||
|
@ -56,7 +58,7 @@ public abstract class Terminal {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Verbosity verbosity = Verbosity.NORMAL;
|
private Verbosity verbosity = Verbosity.NORMAL;
|
||||||
|
private final boolean isDebugEnabled;
|
||||||
|
|
||||||
public Terminal() {
|
public Terminal() {
|
||||||
this(Verbosity.NORMAL);
|
this(Verbosity.NORMAL);
|
||||||
|
@ -64,6 +66,7 @@ public abstract class Terminal {
|
||||||
|
|
||||||
public Terminal(Verbosity verbosity) {
|
public Terminal(Verbosity verbosity) {
|
||||||
this.verbosity = verbosity;
|
this.verbosity = verbosity;
|
||||||
|
this.isDebugEnabled = "true".equals(System.getProperty(DEBUG_SYSTEM_PROPERTY, "false"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verbosity(Verbosity verbosity) {
|
public void verbosity(Verbosity verbosity) {
|
||||||
|
@ -78,6 +81,8 @@ public abstract class Terminal {
|
||||||
|
|
||||||
public abstract char[] readSecret(String text, Object... args);
|
public abstract char[] readSecret(String text, Object... args);
|
||||||
|
|
||||||
|
protected abstract void printStackTrace(Throwable t);
|
||||||
|
|
||||||
public void println() {
|
public void println() {
|
||||||
println(Verbosity.NORMAL);
|
println(Verbosity.NORMAL);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +113,13 @@ public abstract class Terminal {
|
||||||
println(Verbosity.SILENT, "ERROR: " + msg, args);
|
println(Verbosity.SILENT, "ERROR: " + msg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void printError(Throwable t) {
|
||||||
|
printError("%s", t.getMessage());
|
||||||
|
if (isDebugEnabled) {
|
||||||
|
printStackTrace(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void doPrint(String msg, Object... args);
|
protected abstract void doPrint(String msg, Object... args);
|
||||||
|
|
||||||
public abstract PrintWriter writer();
|
public abstract PrintWriter writer();
|
||||||
|
@ -141,6 +153,10 @@ public abstract class Terminal {
|
||||||
return console.writer();
|
return console.writer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(Throwable t) {
|
||||||
|
t.printStackTrace(console.writer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SystemTerminal extends Terminal {
|
private static class SystemTerminal extends Terminal {
|
||||||
|
@ -168,6 +184,11 @@ public abstract class Terminal {
|
||||||
return readText(text, args).toCharArray();
|
return readText(text, args).toCharArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(Throwable t) {
|
||||||
|
t.printStackTrace(printWriter);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrintWriter writer() {
|
public PrintWriter writer() {
|
||||||
return printWriter;
|
return printWriter;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.common.cli;
|
package org.elasticsearch.common.cli;
|
||||||
|
|
||||||
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
|
|
||||||
|
@ -74,6 +75,11 @@ public class CliToolTestCase extends ElasticsearchTestCase {
|
||||||
public void print(String msg, Object... args) {
|
public void print(String msg, Object... args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(Throwable t) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrintWriter writer() {
|
public PrintWriter writer() {
|
||||||
return DEV_NULL;
|
return DEV_NULL;
|
||||||
|
@ -120,6 +126,11 @@ public class CliToolTestCase extends ElasticsearchTestCase {
|
||||||
doPrint(msg, args);
|
doPrint(msg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(Throwable t) {
|
||||||
|
terminalOutput.add(ExceptionsHelper.stackTrace(t));
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getTerminalOutput() {
|
public List<String> getTerminalOutput() {
|
||||||
return terminalOutput;
|
return terminalOutput;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.common.cli;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -224,6 +225,34 @@ public class CliToolTests extends CliToolTestCase {
|
||||||
assertThat(terminal.getTerminalOutput(), hasItem(containsString("cmd1 help")));
|
assertThat(terminal.getTerminalOutput(), hasItem(containsString("cmd1 help")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThatThrowExceptionCanBeLogged() throws Exception {
|
||||||
|
CaptureOutputTerminal terminal = new CaptureOutputTerminal();
|
||||||
|
NamedCommand cmd = new NamedCommand("cmd", terminal) {
|
||||||
|
@Override
|
||||||
|
public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception {
|
||||||
|
throw new ElasticsearchException("error message");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SingleCmdTool tool = new SingleCmdTool("tool", terminal, cmd);
|
||||||
|
assertStatus(tool.execute(), CliTool.ExitStatus.CODE_ERROR);
|
||||||
|
assertThat(terminal.getTerminalOutput(), hasSize(1));
|
||||||
|
assertThat(terminal.getTerminalOutput(), hasItem(containsString("error message")));
|
||||||
|
|
||||||
|
// set env... and log stack trace
|
||||||
|
try {
|
||||||
|
System.setProperty(Terminal.DEBUG_SYSTEM_PROPERTY, "true");
|
||||||
|
terminal = new CaptureOutputTerminal();
|
||||||
|
assertStatus(new SingleCmdTool("tool", terminal, cmd).execute(), CliTool.ExitStatus.CODE_ERROR);
|
||||||
|
assertThat(terminal.getTerminalOutput(), hasSize(2));
|
||||||
|
assertThat(terminal.getTerminalOutput(), hasItem(containsString("error message")));
|
||||||
|
// This class must be part of the stack strace
|
||||||
|
assertThat(terminal.getTerminalOutput(), hasItem(containsString(getClass().getName())));
|
||||||
|
} finally {
|
||||||
|
System.clearProperty(Terminal.DEBUG_SYSTEM_PROPERTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void assertStatus(int status, CliTool.ExitStatus expectedStatus) {
|
private void assertStatus(int status, CliTool.ExitStatus expectedStatus) {
|
||||||
assertThat(status, is(expectedStatus.status()));
|
assertThat(status, is(expectedStatus.status()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue