// // LANforge-GUI Source Code // Copyright (C) 1999-2018 Candela Technologies Inc // http://www.candelatech.com // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // Contact: Candela Technologies if you have any // questions. // import java.util.concurrent.*; import java.io.*; import java.net.URL; import java.util.*; import java.nio.file.*; public class kpi { String lc_osname; String home_dir; 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; public static String TESTBED_TEMPLATE = "testbed_template.html"; public static String AP_AUTO_BASIC_CX = "ap_auto_basic_cx"; public kpi() { priv_init(); } public boolean is_mac() { return lc_osname.startsWith("mac os x"); } public boolean is_win() { return lc_osname.startsWith("windows"); } public boolean is_linux() { return lc_osname.startsWith("linux"); } private void priv_init() { lc_osname = System.getProperty("os.name").toLowerCase(); home_dir = System.getProperty("user.home"); } public static void main(String[] args) { kpi k = new kpi(); try { k.work(args); } catch (Exception ee) { ee.printStackTrace(); } } public void work(String[] args) { String dir = null; for (int i = 0; i test_names = new Hashtable(); Vector test_namesv = new Vector(); Vector runs = new Vector(); try { DirectoryStream stream = Files.newDirectoryStream(Paths.get(dir)); for (Path file: stream) { File f = file.toFile(); // this is the test run dir //System.out.println("Checking sub-directory/file (run): " + f.getAbsolutePath()); // Inside of it is individual tests. if (!f.isDirectory()) { continue; } DirectoryStream stream2 = Files.newDirectoryStream(file); Run run = null; for (Path file2: stream2) { File f2 = file2.toFile(); // this is the test case dir in the test run // Directory full of test results? if (f2.isDirectory()) { File kf = new File(f2.getAbsolutePath() + File.separator + "kpi.csv"); try { BufferedReader br = new BufferedReader(new FileReader(kf)); if (test_names.get(f2.getName()) == null) { test_names.put(f2.getName(), f2.getName()); test_namesv.add(f2.getName()); } if (run == null) { run = new Run(f.getName()); runs.add(run); } Test test = new Test(f2.getName()); run.addTest(test); String line; while ((line = br.readLine()) != null) { test.addLine(line); } } catch (FileNotFoundException enf) { // ignore } catch (Exception e) { e.printStackTrace(); } } } } } catch (IOException | DirectoryIteratorException x) { // IOException can never be thrown by the iteration. // In this snippet, it can only be thrown by newDirectoryStream. System.err.println(x); } // Sort runs so that earliest is first. class SortbyDate implements Comparator { // Used for sorting in ascending order of // roll number public int compare(Run a, Run b) { long c = a.getDateMs() - b.getDateMs(); if (c < 0) return -1; if (c > 0) return 1; return 0; } } runs.sort(new SortbyDate()); // We have read everything into memory. // For each test, generate data over time. Hashtable hist_data = new Hashtable(); Vector hist_datav = new Vector(); for (String tname: test_namesv) { // For each test, find all runs that have this test and consolidate data for (int i = 0; i" + hk + "" + title + "\n"); } catch (Exception ee) { ee.printStackTrace(); } } } String test_bed = "Test Bed"; boolean cp = true; for (int i = 0; i" + run.getName() + "" + run.getDate() + "" + run.getDutHwVer() + "" + run.getDutSwVer() + "" + run.getDutModelNum() + "\n"); if (cp) { try { String fname; copy("CandelaLogo2-90dpi-200x90-trans.png", dir + File.separator + run.getName(), dir); copy("candela_swirl_small-72h.png", dir + File.separator + run.getName(), dir); copy("canvil.ico", dir + File.separator + run.getName(), dir); copy("custom.css", dir + File.separator + run.getName(), dir); copy("report.css", dir + File.separator + run.getName(), dir); cp = false; } catch (Exception ee) { ee.printStackTrace(); } } } try { // Read in the testbed_template.html and update it with our info BufferedReader br = new BufferedReader(new FileReader(new File(kpi.TESTBED_TEMPLATE))); String ofile = dir + File.separator + "index.html"; BufferedWriter bw = new BufferedWriter(new FileWriter(ofile)); String line; while ((line = br.readLine()) != null) { line = line.replace("___TITLE___", test_bed + " Report History"); line = line.replace("___DATA_GRAPHS___", plots.toString()); line = line.replace("___TEST_RUNS___", runs_rows.toString()); bw.write(line); } br.close(); bw.close(); System.out.println("See " + ofile); } catch (Exception eee) { eee.printStackTrace(); } } // ~work() public void copy(String fname, String from, String to) throws Exception { Path fromp = Paths.get(from + File.separator + fname); Path top = Paths.get(to + File.separator + fname); Files.copy(fromp, top, StandardCopyOption.REPLACE_EXISTING); } } class History { String name; Vector csv = new Vector(); Vector csv_names = new Vector(); Hashtable csvh = new Hashtable(); // lookup by name Hashtable titles = new Hashtable(); // lookup by name public History(String n) { name = n; } public String getName() { return name; } StringBuffer findCsv(String n) { //System.out.println("findCsv, n: " + n); return csvh.get(n); } void addCsv(StringBuffer b, String n, String title) { csv.add(b); csv_names.add(n); csvh.put(n, b); titles.put(n, title); } } class Row { Vector rdata = new Vector(); String short_desc_key = null; String getScore() { return rdata.elementAt(kpi.NUMERIC_SCORE_IDX); } String getShortDesc() { return rdata.elementAt(kpi.SHORT_DESC_IDX); } String getTestId() { return rdata.elementAt(kpi.TEST_ID_IDX); } String getShortDescKey() { return short_desc_key; } void setShortDescKey(String s) { short_desc_key = s; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Row " + getShortDescKey() + " "); for (int i = 0; i titles = null; Vector data = new Vector(); Hashtable descs = new Hashtable(); long date_ms = 0; public String date = "NA"; public String test_rig = "NA"; public String dut_hw_version = "NA"; public String dut_sw_version = "NA"; public String dut_model_num = "NA"; public String dut_serial_num = "NA"; public Test(String n) { name = n; } long getDateMs() { return date_ms; } String getTestRig() { return test_rig; } String getDutHwVer() { return dut_hw_version; } String getDutSwVer() { return dut_sw_version; } String getDutSerialNum() { return dut_serial_num; } String getDutModelNum() { System.out.println("Test: " + getName() + " model-num: " + dut_model_num); return dut_model_num; } String getDate() { return date; } String getName() { return name; } void addLine(String l) { if (titles == null) { titles = new Vector(); StringTokenizer st = new StringTokenizer(l, kpi.in_sep, true); boolean last_was_sep = false; while (st.hasMoreTokens()) { String tok = st.nextToken(); if (tok.equals(kpi.in_sep)) { if (last_was_sep) { titles.add(new String()); } last_was_sep = true; } else { titles.add(tok); last_was_sep = false; } } } else { Row row = new Row(); data.add(row); StringTokenizer st = new StringTokenizer(l, kpi.in_sep, true); int idx = 0; System.out.println("new line: " + l); boolean last_was_sep = false; while (st.hasMoreTokens()) { String rtok = st.nextToken(); if (rtok.equals(kpi.in_sep)) { if (last_was_sep) { row.rdata.add(new String()); idx++; } last_was_sep = true; } else { row.rdata.add(rtok); idx++; last_was_sep = false; } if ((data.size() >= 1) && (!last_was_sep) && dut_sw_version.equals("NA")) { // first row is being added if (titles.elementAt(idx - 1).equalsIgnoreCase("test-rig")) { test_rig = rtok; } else if (titles.elementAt(idx - 1).equalsIgnoreCase("dut-hw-version")) { dut_hw_version = rtok; } else if (titles.elementAt(idx - 1).equalsIgnoreCase("dut-sw-version")) { dut_sw_version = rtok; } else if (titles.elementAt(idx - 1).equalsIgnoreCase("dut-model-num")) { dut_model_num = rtok; } else if (titles.elementAt(idx - 1).equalsIgnoreCase("Date")) { //System.out.println("idx: " + idx + " rtok: " + rtok); date_ms = Long.valueOf(rtok).longValue(); date = new Date(date_ms).toString(); } } //System.out.println("idx: " + idx); } //System.out.println("done tok reading loop"); row.setShortDescKey(row.getShortDesc().replace(" ", "_")); //System.out.println("Row: " + row); descs.put(row.getShortDesc(), row.getShortDesc()); } } }//Test class Run { String name; Hashtable tests = new Hashtable(); Vector testsv = new Vector(); public Run(String n) { name = n; } Test getFirstTest() { return testsv.elementAt(0); } String getDate() { Test t = getFirstTest(); if (t != null) return t.getDate(); return ""; } long getDateMs() { Test t = getFirstTest(); if (t != null) return t.getDateMs(); return 0; } String getTestRig() { Test t = getFirstTest(); if (t != null) return t.getTestRig(); return ""; } String getDutHwVer() { Test t = getFirstTest(); if (t != null) return t.getDutHwVer(); return ""; } String getDutSwVer() { Test t = getFirstTest(); if (t != null) return t.getDutSwVer(); return ""; } String getDutModelNum() { Test t = getFirstTest(); if (t != null) return t.getDutModelNum(); return ""; } String getName() { return name; } void addTest(Test t) { tests.put(t.getName(), t); testsv.add(t); } Test findTest(String n) { return tests.get(n); } }//Run // 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; } } }