diff --git a/gui/default.plot b/gui/default.plot new file mode 100644 index 00000000..ee7003d8 --- /dev/null +++ b/gui/default.plot @@ -0,0 +1,10 @@ +set term pngcairo size 1280,768 +set output "plot.png" +set datafile separator "\t" +set ylabel "Data" +set xlabel "Test#" +#set xdata time +set grid +set key outside +plot filename using 1:2 + diff --git a/gui/kpi.java b/gui/kpi.java index 3b26050c..ce53c2a9 100644 --- a/gui/kpi.java +++ b/gui/kpi.java @@ -21,6 +21,7 @@ // questions. // +import java.util.concurrent.*; import java.io.*; import java.net.URL; import java.util.*; @@ -32,6 +33,7 @@ public class kpi { static final String out_sep = "\t"; static final String in_sep = "\t"; + public static int TEST_ID_IDX = 7; public static int SHORT_DESC_IDX = 8; public static int NUMERIC_SCORE_IDX = 10; @@ -147,7 +149,7 @@ public class kpi { StringBuffer csv = hist.findCsv(r.getShortDescKey()); if (csv == null) { csv = new StringBuffer(); - hist.addCsv(csv, r.getShortDescKey()); + hist.addCsv(csv, r.getShortDescKey(), r.getTestId() + ": " + r.getShortDesc()); } csv.append(i + kpi.out_sep + t.data.elementAt(z).getScore() + System.lineSeparator()); } @@ -166,10 +168,23 @@ public class kpi { Set v2 = hist.csv.keySet(); for (String ck: v2) { StringBuffer csv = hist.csv.get(ck); + String title = hist.titles.get(ck); try { - FileWriter f = new FileWriter(dir + File.separator + hk + "::" + ck + ".csv"); + String cf = dir + File.separator + hk + "::" + ck + ".csv"; + FileWriter f = new FileWriter(cf); f.write(csv.toString()); f.close(); + + ShellExec exec = new ShellExec(true, true); + int rv = exec.execute("gnuplot", null, true, "-e", "filename='" + cf + "'", + "-e", "set title '" + title + "'", + "default.plot"); + System.out.println("gnuplot for filename: " + cf + " rv: " + rv); + System.out.println(exec.getOutput()); + System.out.println(exec.getError()); + + File png = new File("plot.png"); + png.renameTo(new File(dir + File.separator + hk + "::" + ck + ".png")); } catch (Exception ee) { ee.printStackTrace(); @@ -182,6 +197,7 @@ public class kpi { class History { Hashtable csv = new Hashtable(); + Hashtable titles = new Hashtable(); public History() { } @@ -191,8 +207,9 @@ class History { return csv.get(n); } - void addCsv(StringBuffer b, String n) { + void addCsv(StringBuffer b, String n, String title) { csv.put(n, b); + titles.put(n, title); } } @@ -208,6 +225,10 @@ class Row { return rdata.elementAt(kpi.SHORT_DESC_IDX); } + String getTestId() { + return rdata.elementAt(kpi.TEST_ID_IDX); + } + String getShortDescKey() { return short_desc_key; } @@ -332,3 +353,143 @@ class Run { return tests.get(n); } } + + +// From: https://stackoverflow.com/questions/882772/capturing-stdout-when-calling-runtime-exec + +/** + * Execute external process and optionally read output buffer. + */ +class ShellExec { + private int exitCode; + private boolean readOutput, readError; + private StreamGobbler errorGobbler, outputGobbler; + + public ShellExec() { + this(false, false); + } + + public ShellExec(boolean readOutput, boolean readError) { + this.readOutput = readOutput; + this.readError = readError; + } + + /** + * Execute a command. + * @param command command ("c:/some/folder/script.bat" or "some/folder/script.sh") + * @param workdir working directory or NULL to use command folder + * @param wait wait for process to end + * @param args 0..n command line arguments + * @return process exit code + */ + public int execute(String command, String workdir, boolean wait, String...args) throws IOException { + String[] cmdArr; + if (args != null && args.length > 0) { + cmdArr = new String[1+args.length]; + cmdArr[0] = command; + System.arraycopy(args, 0, cmdArr, 1, args.length); + } else { + cmdArr = new String[] { command }; + } + + ProcessBuilder pb = new ProcessBuilder(cmdArr); + File workingDir = (workdir==null ? new File(command).getParentFile() : new File(workdir) ); + pb.directory(workingDir); + + Process process = pb.start(); + + // Consume streams, older jvm's had a memory leak if streams were not read, + // some other jvm+OS combinations may block unless streams are consumed. + errorGobbler = new StreamGobbler(process.getErrorStream(), readError); + outputGobbler = new StreamGobbler(process.getInputStream(), readOutput); + errorGobbler.start(); + outputGobbler.start(); + + exitCode = 0; + if (wait) { + try { + process.waitFor(); + exitCode = process.exitValue(); + } catch (InterruptedException ex) { } + } + return exitCode; + } + + public int getExitCode() { + return exitCode; + } + + public boolean isOutputCompleted() { + return (outputGobbler != null ? outputGobbler.isCompleted() : false); + } + + public boolean isErrorCompleted() { + return (errorGobbler != null ? errorGobbler.isCompleted() : false); + } + + public String getOutput() { + return (outputGobbler != null ? outputGobbler.getOutput() : null); + } + + public String getError() { + return (errorGobbler != null ? errorGobbler.getOutput() : null); + } + + //******************************************** + //******************************************** + + /** + * StreamGobbler reads inputstream to "gobble" it. + * This is used by Executor class when running + * a commandline applications. Gobblers must read/purge + * INSTR and ERRSTR process streams. + * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 + */ + private class StreamGobbler extends Thread { + private InputStream is; + private StringBuilder output; + private volatile boolean completed; // mark volatile to guarantee a thread safety + + public StreamGobbler(InputStream is, boolean readStream) { + this.is = is; + this.output = (readStream ? new StringBuilder(256) : null); + } + + public void run() { + completed = false; + try { + String NL = System.getProperty("line.separator", "\r\n"); + + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line; + while ( (line = br.readLine()) != null) { + if (output != null) + output.append(line + NL); + } + } catch (IOException ex) { + // ex.printStackTrace(); + } + completed = true; + } + + /** + * Get inputstream buffer or null if stream + * was not consumed. + * @return + */ + public String getOutput() { + return (output != null ? output.toString() : null); + } + + /** + * Is input stream completed. + * @return + */ + public boolean isCompleted() { + return completed; + } + + } + +}