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:
Alexander Reelsen 2014-08-11 18:20:53 +02:00
parent 9e6868733c
commit e689a0ad71
4 changed files with 65 additions and 4 deletions

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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()));
} }