mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-10-31 18:58:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1387 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			1387 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| //
 | |
| // LANforge-GUI Source Code
 | |
| // Copyright (C) 1999-2020  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 <support@candelatech.com> if you have any
 | |
| //           questions.
 | |
| //
 | |
| 
 | |
| import java.text.*;
 | |
| import java.util.concurrent.*;
 | |
| import java.io.*;
 | |
| import java.net.URL;
 | |
| import java.util.*;
 | |
| import java.nio.file.*;
 | |
| 
 | |
| /** Process a set of test results generated by the CI/CD process for a test type in a single testbed.
 | |
|  * There are currently no automated comparisons done across different testbeds.
 | |
|  * Generate historical graphs and links to each test run.
 | |
|  * Each test results directory would be packaged up by the lf_gui_report_summary.pl script,
 | |
|  * called by the basic_regression.bash automated regression test script.
 | |
|  * Example:  java kpi --dir /var/www/html/tip/testbeds/ferndale-basic-01/reports/basic
 | |
|  */
 | |
| public class kpi {
 | |
|    String lc_osname;
 | |
|    String home_dir;
 | |
| 
 | |
|    static final String out_sep = "\t";
 | |
|    static final String in_sep = "\t";
 | |
|    
 | |
|    public static int PRIORITY_IDX = 6;
 | |
|    public static int TEST_ID_IDX = 7;
 | |
|    public static int SHORT_DESC_IDX = 8;
 | |
|    public static int PASS_FAIL_IDX = 9;
 | |
|    public static int NUMERIC_SCORE_IDX = 10;
 | |
|    public static int NOTES_IDX = 11;
 | |
|    public static int UNITS_IDX = 12;
 | |
|    public static int GRAPH_GROUP_IDX = 13;
 | |
|    public static int SUBTEST_PASS_IDX = 14;
 | |
|    public static int SUBTEST_FAIL_IDX = 15;
 | |
| 
 | |
|    public static String TESTBED_TEMPLATE = "testbed_template.html";
 | |
|    public static String AP_AUTO_BASIC_CX = "ap_auto_basic_cx";
 | |
| 
 | |
|    public static String HTML_COLOR_PASS = "#bee7aa";
 | |
|    public static String HTML_COLOR_FAIL = "#f9c5c0";
 | |
|    public static String HTML_COLOR_WARNING = "#f8f6ad";
 | |
| 
 | |
|    public static String PF = "PASS-FAIL";
 | |
| 
 | |
|    public kpi() {
 | |
|       priv_init();
 | |
|    }
 | |
| 
 | |
|    static String yellowTd(String txt) {
 | |
|       return "<td><span style='background:" + HTML_COLOR_WARNING + ";color:black;'>" + txt + "</span></td>";
 | |
|    }
 | |
| 
 | |
|    static String redTd(String txt) {
 | |
|       return "<td><span style='background:" + HTML_COLOR_FAIL + ";color:black;'>" + txt + "</span></td>";
 | |
|    }
 | |
| 
 | |
|    static String greenTd(String txt) {
 | |
|       return "<td><span style='background:" + HTML_COLOR_PASS + ";color:black;'>" + txt + "</span></td>";
 | |
|    }
 | |
| 
 | |
|    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 static String toStringNum(double i, int precision) {
 | |
|       NumberFormat nf = NumberFormat.getInstance();
 | |
|       if (0.0 == i) {
 | |
|          // Don't pad precision on '0', just adds needless clutter.
 | |
|          return nf.format(i);
 | |
|       }
 | |
|       else {
 | |
|          nf = (NumberFormat)(nf.clone());
 | |
|          nf.setMaximumFractionDigits(precision);
 | |
|          nf.setMinimumFractionDigits(precision);
 | |
|          return nf.format(i);
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    public void work(String[] args) {
 | |
|       String dir = null;
 | |
|       String results_url = "";
 | |
|       String caseid = "";
 | |
|       String slack_fname = "";
 | |
|       String testbed_name = "LANforge CICD";
 | |
| 
 | |
|       for (int i = 0; i<args.length; i++) {
 | |
|          if (args[i].equals("--dir")) {
 | |
|             dir = args[i+1];
 | |
|          }
 | |
|          else if (args[i].equals("--caseid")) {
 | |
|             caseid = args[i+1];
 | |
|          }
 | |
|          else if (args[i].equals("--results_url")) {
 | |
|             results_url = args[i+1];
 | |
|          }
 | |
|          else if (args[i].equals("--slack_fname")) {
 | |
|             slack_fname = args[i+1];
 | |
|          }
 | |
|          else if (args[i].equals("--testbed_name")) {
 | |
|             testbed_name = args[i+1];
 | |
|          }
 | |
|          else if (args[i].equals("--help") || args[i].equals("-h") || args[i].equals("-?")) {
 | |
|             System.out.println("Usage: $0 --dir /path/to/test-collection\n" +
 | |
|                                "--caseid [case-id]\n" +
 | |
|                                "--results_url [url]\n" +
 | |
|                                "--slack_fname [slack url webhook file name]\n" +
 | |
|                                "--testbed_name [My Testbed]");
 | |
|             System.exit(0);
 | |
|          }
 | |
|       }
 | |
| 
 | |
|       Hashtable<String, String> test_names = new Hashtable();
 | |
|       Vector<String> test_namesv = new Vector();
 | |
|       Vector<Run> runs = new Vector();
 | |
| 
 | |
|       test_names.put(PF, PF);
 | |
|       test_namesv.add(PF);
 | |
| 
 | |
|       try {
 | |
|          DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir));
 | |
|          for (Path file: stream) {
 | |
|             File f = file.toFile(); // this is the test run dir
 | |
|             // Inside of it is individual tests.
 | |
|             if (!f.isDirectory()) {
 | |
|                continue;
 | |
|             }
 | |
|             //System.out.println("Checking sub-directory/file (run): " + f.getAbsolutePath());
 | |
|             DirectoryStream<Path> 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
 | |
|                //System.out.println("Checking test-case directory/file: " + f2.getAbsolutePath());
 | |
|                // Directory full of test results?
 | |
|                if (f2.isDirectory()) {
 | |
|                   DirectoryStream<Path> stream3 = Files.newDirectoryStream(file2);
 | |
|                   Test test = new Test(f2.getName());
 | |
|                   if (run == null) {
 | |
|                      run = new Run(f.getName());
 | |
|                      runs.add(run);
 | |
|                   }
 | |
|                   System.out.println("Run: " + run + " adding test: " + test);
 | |
|                   run.addTest(test);
 | |
| 
 | |
|                   // TODO:
 | |
|                   // Add log processing.  In particular, look in console logs for things like:
 | |
|                   // "ath10k_pci 0000:01:00.0: wmi command 36967 timeout, restarting hardware"
 | |
|                   // "WARNING: CPU: 0 PID: 8907 at backports-4.
 | |
| 
 | |
|                   for (Path file3: stream3) {
 | |
|                      File f3 = file3.toFile();
 | |
|                      String fname = f3.getName();
 | |
|                      if (fname.equals("kpi.csv")) {
 | |
|                         try {
 | |
|                            BufferedReader br = new BufferedReader(new FileReader(f3));
 | |
|                            if (test_names.get(f2.getName()) == null) {
 | |
|                               test_names.put(f2.getName(), f2.getName());
 | |
|                               test_namesv.add(f2.getName());
 | |
|                            }
 | |
|                            String line;
 | |
|                            while ((line = br.readLine()) != null) {
 | |
|                               test.addLine(line);
 | |
|                            }
 | |
|                         }
 | |
|                         catch (FileNotFoundException enf) {
 | |
|                            // ignore
 | |
|                         }
 | |
|                         catch (Exception e) {
 | |
|                            e.printStackTrace();
 | |
|                         }
 | |
|                      }// if kpi.csv
 | |
|                      else if (fname.startsWith("kpi-") && fname.endsWith(".png")) {
 | |
|                         test.addKpiImage(fname);
 | |
|                      }
 | |
|                      else if (fname.equals("logs")) {
 | |
|                         File logs_csv = new File(f3.getAbsolutePath() + File.separator + "logs.csv");
 | |
|                         if (logs_csv.exists()) {
 | |
|                            try {
 | |
|                               BufferedReader br = new BufferedReader(new FileReader(logs_csv));
 | |
|                               String line;
 | |
|                               while ((line = br.readLine()) != null) {
 | |
|                                  test.addLogCsv(line);
 | |
|                               }
 | |
|                            }
 | |
|                            catch (Exception e) {
 | |
|                               e.printStackTrace();
 | |
|                            }
 | |
|                         }
 | |
|                      }
 | |
|                   }// for all files in the test dir  
 | |
|                }
 | |
|             }
 | |
|          }
 | |
|       } 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<Run> { 
 | |
|          // 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());
 | |
| 
 | |
|       // Create meta-test results for each run.
 | |
|       for (int i = 0; i<runs.size(); i++) {
 | |
|          Run run = runs.elementAt(i);
 | |
|          Test t = new Test(PF);
 | |
|          run.addTest(t);
 | |
|          // Build fake kpi title and add that,
 | |
|          // then add fake kpi results line
 | |
|          // Example lines from a kpi.csv
 | |
|          //Date	test-rig	dut-hw-version	dut-sw-version	dut-model-num	dut-serial-num	test-priority	test-id	short-description	pass/fail	numeric-score	test details	Units	Graph-Group	Subtest-Pass	Subtest-Fail
 | |
|          //1590190791848	Ferndale-01-Basic	Linksys-EA8300	d88ea40	Linksys-EA8300		90	AP Auto	Basic Client Connectivity Dual-Band MIN		8.0	Minimum CX time (ms)	Time (ms)	CX-Time	0	0
 | |
| 
 | |
|          t.addLine("Date	test-rig	dut-hw-version	dut-sw-version	dut-model-num	dut-serial-num	test-priority	test-id	short-description	pass/fail	numeric-score	test details	Units	Graph-Group	Subtest-Pass	Subtest-Fail");
 | |
|          t.addLine(run.getDateMs() + kpi.in_sep + run.getTestRig() + kpi.in_sep + run.getDutHwVer() + kpi.in_sep + run.getDutSwVer()
 | |
|                    + kpi.in_sep + run.getDutModelNum() + kpi.in_sep + run.getDutSerNum() + kpi.in_sep + "100" + kpi.in_sep + PF
 | |
|                    + kpi.in_sep + "Total Pass" + kpi.in_sep + kpi.in_sep + run.getPass() + kpi.in_sep + "Total passing tests and sub-tests for this run."
 | |
|                    + kpi.in_sep + "Number" + kpi.in_sep + PF + kpi.in_sep + "0" + kpi.in_sep + "0");
 | |
|          t.addLine(run.getDateMs() + kpi.in_sep + run.getTestRig() + kpi.in_sep + run.getDutHwVer() + kpi.in_sep + run.getDutSwVer()
 | |
|                    + kpi.in_sep + run.getDutModelNum() + kpi.in_sep + run.getDutSerNum() + kpi.in_sep + "100" + kpi.in_sep + PF
 | |
|                    + kpi.in_sep + "Total Failures" + kpi.in_sep + kpi.in_sep + run.getFail() + kpi.in_sep + "Total failing tests and sub-tests for this run."
 | |
|                    + kpi.in_sep + "Number" + kpi.in_sep + PF + kpi.in_sep + "0" + kpi.in_sep + "0");
 | |
|       }
 | |
| 
 | |
|       // Link to latest test run that has the test id
 | |
|       Hashtable<String, Run> test_id_links = new Hashtable();
 | |
| 
 | |
|       // We have read everything into memory.
 | |
|       // For each test, generate data over time.
 | |
|       Hashtable<String, History> hist_data = new Hashtable();
 | |
|       Vector<History> hist_datav = new Vector();
 | |
|       for (String tname: test_namesv) {
 | |
|          System.out.println("Checking testname: " + tname + " runs.size: " + runs.size());
 | |
|          // For each test, find all runs that have this test and consolidate data
 | |
|          for (int i = 0; i<runs.size(); i++) {
 | |
|             Run run = runs.elementAt(i);
 | |
|             Test t = run.findTest(tname);
 | |
|             System.out.println("Run [" + i + "]  Test: " + t);
 | |
|             if (t != null) {
 | |
|                test_id_links.put(tname, run);
 | |
|                try {
 | |
|                   History hist = hist_data.get(tname);
 | |
|                   if (hist == null) {
 | |
|                      hist = new History(tname);
 | |
|                      hist_data.put(tname, hist);
 | |
|                      hist_datav.add(hist);
 | |
|                      System.out.println("Adding history datav, tname: " + tname);
 | |
|                   }
 | |
|                   for (int z = 0; z<t.data.size(); z++) {
 | |
|                      Row r = t.data.elementAt(z);
 | |
|                      HistRow csv = hist.findRow(r.getShortDescKey());
 | |
|                      if (csv == null) {
 | |
|                         csv = new HistRow(r);
 | |
|                         hist.addRow(csv);
 | |
|                         System.out.println("Adding history row: " + r.getShortDescKey());
 | |
|                      }
 | |
|                      String score =  t.data.elementAt(z).getScore();
 | |
|                      csv.csv.append(i + kpi.out_sep + score + System.lineSeparator());
 | |
|                      csv.scores.add(Double.valueOf(score));
 | |
|                   }
 | |
|                }
 | |
|                catch (Exception eee) {
 | |
|                   eee.printStackTrace();
 | |
|                }
 | |
|             }
 | |
|          }
 | |
|       }
 | |
| 
 | |
|       StringBuffer scores = new StringBuffer();
 | |
|       StringBuffer plots = new StringBuffer();
 | |
|       StringBuffer groups = new StringBuffer();
 | |
|       StringBuffer runs_rows = new StringBuffer();
 | |
| 
 | |
|       // For all per-test history, print out csv files
 | |
|       for (History hist : hist_datav) {
 | |
|          String hk = hist.getName();
 | |
|          Hashtable<String, Vector> groupsh = new Hashtable();
 | |
|          Vector<String> groupsn = new Vector();
 | |
|          System.out.println("Checking history-data: " + hk);
 | |
|          for (HistRow csv : hist.csv) {
 | |
|             String ck = csv.getName();
 | |
|             String title = csv.getTitle();
 | |
|             String units = csv.getUnits();
 | |
|             String g = csv.getGraphGroup();
 | |
| 
 | |
|             System.out.println("csv name: " + ck);
 | |
| 
 | |
|             if (!(g.equals("NA") || units.equals(""))) {
 | |
|                Vector<HistRow> gv = groupsh.get(g);
 | |
|                if (gv == null) {
 | |
|                   gv = new Vector();
 | |
|                   groupsh.put(g, gv);
 | |
|                   groupsn.add(g);
 | |
|                }
 | |
|                gv.add(csv);
 | |
|             }
 | |
| 
 | |
|             if (units.equals("NA") || units.equals("")) {
 | |
|                units = "Data";
 | |
|             }
 | |
|             try {
 | |
|                String cf = dir + File.separator + hk + "::" + ck + ".csv";
 | |
|                System.out.println("Creating gnuplot csv: " + cf);
 | |
|                FileWriter f = new FileWriter(cf);
 | |
|                f.write(csv.csv.toString());
 | |
|                f.close();
 | |
|                csv.setFname(cf);
 | |
| 
 | |
|                ShellExec exec = new ShellExec(true, true);
 | |
|                int rv = exec.execute("gnuplot", null, true,
 | |
|                                      "-e", "set ylabel \"" + units + "\"",
 | |
|                                      "-e", "filename='" + cf + "'",
 | |
|                                      "-e", "set title '" + title + "'",
 | |
|                                      "default.plot");
 | |
|                if (rv != 0) {
 | |
|                   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");
 | |
|                if (!png.exists()) {
 | |
|                   System.out.println("ERROR:  File: " + png + " does not exist.");
 | |
|                }
 | |
|                String npng = hk + "::" + ck + ".png";
 | |
|                String nplot_name = dir + File.separator + npng;
 | |
|                System.out.println("Rename plot: " + png + " to: " + nplot_name);
 | |
|                File nf = new File(nplot_name);
 | |
|                Path nfp = Files.move(png.toPath(), nf.toPath(), StandardCopyOption.REPLACE_EXISTING);//boolean renamed = png.renameTo(nf);
 | |
|                if (!nf.exists()) {
 | |
|                   System.out.println("ERROR:  New file: " + nf + " does not exist.");
 | |
|                }
 | |
| 
 | |
|                exec = new ShellExec(true, true);
 | |
|                rv = exec.execute("gnuplot", null, true, "-e", "filename='" + cf + "'",
 | |
|                                      "mini.plot");
 | |
|                if (rv != 0) {
 | |
|                   System.out.println("mini gnuplot for filename: " + cf + " rv: " + rv);
 | |
|                   System.out.println(exec.getOutput());
 | |
|                   System.out.println(exec.getError());
 | |
|                }
 | |
| 
 | |
|                png = new File("plot.png");
 | |
|                String npngt = hk + "::" + ck + "-thumb.png";
 | |
|                Files.move(png.toPath(), new File(dir + File.separator + npngt).toPath(), StandardCopyOption.REPLACE_EXISTING);
 | |
|                
 | |
|                String hk_str = hk;
 | |
|                Run last = test_id_links.get(hk);
 | |
|                if (!hk.equals(PF)) {
 | |
|                   if (last != null) {
 | |
|                      hk_str = "<a href=\"" + last.getName() + "/" + hk + "/index.html\">" + hk + "</a>";
 | |
|                   }
 | |
|                }
 | |
| 
 | |
|                StringBuffer change = new StringBuffer();
 | |
|                Double cur = csv.scores.elementAt(csv.scores.size() - 1);
 | |
|                change.append("Last Value: " + toStringNum(cur, 2));
 | |
|                if (csv.scores.size() > 1) {
 | |
|                   Double prev = csv.scores.elementAt(csv.scores.size() - 2);
 | |
|                   change.append("<br>Delta for last run: " + toStringNum((cur - prev), 2));
 | |
|                   if (cur != 0) {
 | |
|                      change.append("<br>Percentage change: " + toStringNum(100.0 * ((cur - prev) / cur), 2) + "%");
 | |
|                   }
 | |
|                }
 | |
| 
 | |
|                String row_str = ("<tr><td>" + hk_str + "</td><td>" + title + "</td><td><a href=\"./" + npng + "\"><img src=\"./" + npngt + "\"></a></td><td>"
 | |
|                                  + change + "</td></tr>\n");
 | |
|                if (csv.getPriority() >= 100) {
 | |
|                   scores.append(row_str);
 | |
|                }
 | |
|                else {
 | |
|                   plots.append(row_str);
 | |
|                }
 | |
|             }
 | |
|             catch (Exception ee) {
 | |
|                ee.printStackTrace();
 | |
|             }
 | |
|          }
 | |
| 
 | |
|          // Graph groups
 | |
|          for (String g : groupsn) {
 | |
|             Vector<HistRow> datasets = groupsh.get(g);
 | |
|             if (datasets.size() < 2) {
 | |
|                continue; // group of 1 doesn't count
 | |
|             }
 | |
| 
 | |
|             HistRow csv0 = datasets.elementAt(0);
 | |
|             String title = g;
 | |
|             String units = csv0.getUnits();
 | |
| 
 | |
|             // Don't group scores
 | |
|             if (units.equalsIgnoreCase("Score")) {
 | |
|                continue;
 | |
|             }
 | |
| 
 | |
|             if (units.equals("NA") || units.equals("")) {
 | |
|                units = "Data";
 | |
|             }
 | |
| 
 | |
|             System.out.println("title: " + title + " units: " + units);
 | |
|             try {
 | |
|                StringBuffer plot = new StringBuffer("plot ");
 | |
|                StringBuffer mplot = new StringBuffer("plot ");
 | |
|                boolean first = true;
 | |
|                for (HistRow csv: datasets) {
 | |
|                   if (!first) {
 | |
|                      plot.append(", ");
 | |
|                      mplot.append(", ");
 | |
|                   }
 | |
|                   plot.append("\'" + csv.getFname() + "\' using 1:2 with lines title \'" + csv.getName().replace("_", " ") + "\'");
 | |
|                   mplot.append("\'" + csv.getFname() + "\' using 1:2 with lines notitle");
 | |
|                   first = false;
 | |
|                }
 | |
| 
 | |
|                BufferedReader br = new BufferedReader(new FileReader("default_group.plot"));
 | |
|                FileWriter f = new FileWriter("tmp.plot");
 | |
|                String line;
 | |
|                while ((line = br.readLine()) != null) {
 | |
|                   f.write(line);
 | |
|                   f.write(System.lineSeparator());
 | |
|                }
 | |
|                f.write(plot.toString());
 | |
|                f.write(System.lineSeparator());
 | |
|                f.close();
 | |
|                br.close();
 | |
| 
 | |
|                //System.out.println("group plot: " + plot);
 | |
|                ShellExec exec = new ShellExec(true, true);
 | |
|                int rv = exec.execute("gnuplot", null, true,
 | |
|                                      "-e", "set ylabel '" + units + "'",
 | |
|                                      "-e", "set title '" + title + "'",
 | |
|                                      "tmp.plot");
 | |
|                if (rv != 0) {
 | |
|                   System.out.println("gnuplot for group: " + title + " rv: " + rv);
 | |
|                   System.out.println(exec.getOutput());
 | |
|                   System.out.println(exec.getError());
 | |
|                }
 | |
| 
 | |
|                File png = new File("plot.png");
 | |
|                String npng = hk + "::" + g + ".png";
 | |
|                Files.move(png.toPath(), new File(dir + File.separator + npng).toPath(), StandardCopyOption.REPLACE_EXISTING);
 | |
| 
 | |
|                br = new BufferedReader(new FileReader("mini_group.plot"));
 | |
|                f = new FileWriter("tmp.plot");
 | |
|                while ((line = br.readLine()) != null) {
 | |
|                   f.write(line);
 | |
|                   f.write(System.lineSeparator());
 | |
|                }
 | |
|                f.write(mplot.toString());
 | |
|                f.write(System.lineSeparator());
 | |
|                f.close();
 | |
|                br.close();
 | |
| 
 | |
|                exec = new ShellExec(true, true);
 | |
|                rv = exec.execute("gnuplot", null, true,
 | |
|                                  "tmp.plot");
 | |
|                if (rv != 0) {
 | |
|                   System.out.println("mini gnuplot for group: " + title + " rv: " + rv);
 | |
|                   System.out.println(exec.getOutput());
 | |
|                   System.out.println(exec.getError());
 | |
|                }
 | |
| 
 | |
|                png = new File("plot.png");
 | |
|                String npngt = hk + "::" + g + "-thumb.png";
 | |
|                Files.move(png.toPath(), new File(dir + File.separator + npngt).toPath(), StandardCopyOption.REPLACE_EXISTING);
 | |
| 
 | |
|                String hk_str = hk;
 | |
|                Run last = test_id_links.get(hk);
 | |
|                if (!hk.equals(PF)) {
 | |
|                   if (last != null) {
 | |
|                      hk_str = "<a href=\"" + last.getName() + "/" + hk + "/index.html\">" + hk + "</a>";
 | |
|                   }
 | |
|                }
 | |
| 
 | |
|                groups.append("<tr><td>" + hk_str + "</td><td>" + title + "</td><td><a href=\"./" + npng + "\"><img src=\"./" + npngt + "\"></a></td></tr>\n");
 | |
| 
 | |
|             }
 | |
|             catch (Exception ee) {
 | |
|                ee.printStackTrace();
 | |
|             }
 | |
|          }
 | |
|          
 | |
|       }
 | |
| 
 | |
|       String test_bed = "Test Bed";
 | |
|       String last_run = "";
 | |
|       String last_run_kpi_images = "";
 | |
|       StringBuffer pngs = new StringBuffer();
 | |
| 
 | |
|       boolean cp = true;
 | |
|       for (int i = 0; i<runs.size(); i++) {
 | |
|          Run run = runs.elementAt(i);
 | |
|          test_bed = run.getTestRig();
 | |
|          StringBuffer logs_str = new StringBuffer();
 | |
|          int logv = run.getLogBugs();
 | |
|          if (logv > 0) {
 | |
|             logs_str.append(redTd(logv + ""));
 | |
|          }
 | |
|          else {
 | |
|             logs_str.append(greenTd(logv + ""));
 | |
|          }
 | |
| 
 | |
|          logv = run.getLogWarnings();
 | |
|          if (logv > 0) {
 | |
|             logs_str.append(redTd(logv + ""));
 | |
|          }
 | |
|          else {
 | |
|             logs_str.append(greenTd(logv + ""));
 | |
|          }
 | |
| 
 | |
|          logv = run.getLogCrashes();
 | |
|          if (logv > 0) {
 | |
|             logs_str.append(redTd(logv + ""));
 | |
|          }
 | |
|          else {
 | |
|             logs_str.append(greenTd(logv + ""));
 | |
|          }
 | |
| 
 | |
|          logv = run.getLogRestarting();
 | |
|          if (logv > 0) {
 | |
|             logs_str.append(redTd(logv + ""));
 | |
|          }
 | |
|          else {
 | |
|             logs_str.append(greenTd(logv + ""));
 | |
|          }
 | |
| 
 | |
|          String row_text = ("<tr><td>" + i + "</td><td><a href=\"" + run.getName() + "/index.html\">" + run.getName() + "</a></td><td>" + run.getDate()
 | |
|                             + "</td><td>" + run.getDutHwVer() + "</td><td>" + run.getDutSwVer()
 | |
|                             + "</td><td>" + run.getDutModelNum() + "</td>" + greenTd(run.getPass() + "") + redTd(run.getFail() + "") + logs_str + "</tr>\n");
 | |
|             
 | |
|          if (i == (runs.size() - 1)) {
 | |
|             // Last run
 | |
|             int png_row_count = 0;
 | |
|             boolean needs_tr = true;
 | |
|             last_run = row_text;
 | |
|             for (Test t : run.testsv) {
 | |
|                for (String png : t.kpi_images) {
 | |
|                   if (png.indexOf("-print") >= 0) {
 | |
|                      continue; // skip the print variants of the image.
 | |
|                   }
 | |
|                   if (needs_tr) {
 | |
|                      pngs.append("<tr>");
 | |
|                      needs_tr = false;
 | |
|                   }
 | |
|                   String img_title = "Test: " + t.getName();
 | |
|                   String fname = run.getName() + "/" + t.getName() + "/" + png;
 | |
|                   pngs.append("<td><a href=\"" + fname + "\"><img src=\"" + fname + "\" style='width:400px;max-width:400px' title=\""
 | |
|                               + img_title + "\"></a></td>\n");
 | |
|                   png_row_count++;
 | |
|                   if (png_row_count == 2) {
 | |
|                      png_row_count = 0;
 | |
|                      pngs.append("</tr>\n");
 | |
|                      needs_tr = true;
 | |
|                   }
 | |
|                }
 | |
|             }
 | |
| 
 | |
|             if ((!needs_tr) && pngs.length() > 0) {
 | |
|                pngs.append("</tr>\n");
 | |
|             }
 | |
| 
 | |
|             String testrails_msg = ("MSG Run: " + run.getName() + " Date: " + run.getDate() + " DUT-HW: " + run.getDutHwVer() + "DUT-SW: " + run.getDutSwVer()
 | |
|                                     + " Passed: " + run.getPass() + " Fail: " + run.getFail()
 | |
|                                     + " Log-Bugs: " + run.getLogBugs() + " Log-Warnings: " + run.getLogWarnings()
 | |
|                                     + " Log-Crashes: " + run.getLogCrashes() + " Log-Restarting: " + run.getLogRestarting());
 | |
| 
 | |
|             if (!caseid.equals("")) {
 | |
|                try {
 | |
|                   // Create file for propagating results into external tool
 | |
|                   String ofile = dir + File.separator + "testrails.txt";
 | |
|                   BufferedWriter bw = new BufferedWriter(new FileWriter(ofile));
 | |
|              
 | |
|                   bw.write("CASE_ID " + caseid);
 | |
|                   bw.write(System.lineSeparator());
 | |
|                   bw.write("RUN_ID " + i);
 | |
|                   bw.write(System.lineSeparator());
 | |
|                   bw.write(testrails_msg);
 | |
|                   bw.write(System.lineSeparator());
 | |
|                   bw.write("MSG URL: " + results_url + "/" + run.getName());
 | |
|                   bw.write(System.lineSeparator());
 | |
| 
 | |
|                   bw.close();
 | |
| 
 | |
|                   System.out.println("See testrails results: " + ofile);
 | |
|                }
 | |
|                catch (Exception eee) {
 | |
|                   eee.printStackTrace();
 | |
|                }
 | |
|             }
 | |
| 
 | |
|             if (!slack_fname.equals("")) {
 | |
|                String slack_content_type = "Content-type: application/json";
 | |
|                String slack_msg = "{\"text\":\"<" + results_url + "|" + testbed_name + ">"
 | |
|                   + " Results: <" + results_url + "/" + run.getName() + "|" + run.getName() + ">"
 | |
|                   + " Errors: " + (run.getLogCrashes() + run.getLogRestarting() + run.getLogBugs()) + " Warnings: " + run.getLogWarnings()
 | |
|                   + "\"}";
 | |
|                try {
 | |
|                   BufferedReader br = new BufferedReader(new FileReader(slack_fname));
 | |
|                   String slack = br.readLine();
 | |
|                   String cmd = "curl -X POST -H '" + slack_content_type + "' --data '" + slack_msg + "' " + slack;
 | |
|                   System.out.println(cmd);
 | |
| 
 | |
|                   ShellExec exec = new ShellExec(true, true);
 | |
|                   int rv = exec.execute("curl", null, true,
 | |
|                                         "-X", "POST",
 | |
|                                         "-H", slack_content_type,
 | |
|                                         "--data", slack_msg, slack);
 | |
|                   if (rv != 0) {
 | |
|                      System.out.println("curl slack post of msg: " + slack_msg + " to: " + slack + " failed.\n");
 | |
|                      System.out.println(exec.getOutput());
 | |
|                      System.out.println(exec.getError());
 | |
|                   }
 | |
|                }
 | |
|                catch (Exception eeee) {
 | |
|                   System.out.println("slack_msg: " + slack_msg + " slack_fname: " + slack_fname);
 | |
|                   eeee.printStackTrace();
 | |
|                }
 | |
|             }
 | |
|          }
 | |
| 
 | |
|          runs_rows.append(row_text);
 | |
| 
 | |
|          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("___SCORE_RUNS___", scores.toString());
 | |
|             line = line.replace("___GROUP_GRAPHS___", groups.toString());
 | |
|             line = line.replace("___DATA_GRAPHS___", plots.toString());
 | |
|             line = line.replace("___TEST_RUNS___", runs_rows.toString());
 | |
|             line = line.replace("___LATEST_RUN___", last_run);
 | |
|             line = line.replace("___LATEST_RUN_PNGS___", pngs.toString());
 | |
|             bw.write(line);
 | |
|             bw.write(System.lineSeparator());
 | |
|          }
 | |
|          
 | |
|          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);
 | |
|    }
 | |
| }
 | |
| 
 | |
| 
 | |
| /** This holds a datapoint for a particular test result for each of the Runs.
 | |
|  * This is used to generate historical graphs and comparisons.
 | |
|  * If a test generates two KPI results, there will be two HistRows for that
 | |
|  * test case.
 | |
|  */
 | |
| class HistRow {
 | |
|    String fname;
 | |
|    String name;
 | |
|    String title = "";
 | |
|    String units = "";
 | |
|    String graph_group = "";
 | |
|    int prio = 0;
 | |
|    StringBuffer csv = new StringBuffer();
 | |
|    Vector<Double> scores = new Vector();
 | |
| 
 | |
|    public HistRow(Row r) {
 | |
|       name = r.getShortDescKey();
 | |
|       title = r.getShortDesc();
 | |
|       units = r.getUnits();
 | |
|       graph_group = r.getGraphGroup();
 | |
|       prio = r.getPriority();
 | |
|    }
 | |
| 
 | |
|    int getPriority() {
 | |
|       return prio;
 | |
|    }
 | |
| 
 | |
|    String getFname() {
 | |
|       return fname;
 | |
|    }
 | |
| 
 | |
|    void setFname(String s) {
 | |
|       fname = s;
 | |
|    }
 | |
| 
 | |
|    String getName() {
 | |
|       return name;
 | |
|    }
 | |
| 
 | |
|    String getTitle() {
 | |
|       return title;
 | |
|    }
 | |
| 
 | |
|    String getUnits() {
 | |
|       return units;
 | |
|    }
 | |
| 
 | |
|    String getGraphGroup() {
 | |
|       return graph_group;
 | |
|    }
 | |
| }
 | |
| 
 | |
| /** This holds all HistRow objects for each test name for each run.
 | |
|  * It is used for generating historical graphs and comparisons.
 | |
|  */
 | |
| class History {
 | |
|    String name;
 | |
|    Vector<HistRow> csv = new Vector();
 | |
|    Hashtable<String, HistRow> csvh = new Hashtable(); // lookup by name
 | |
| 
 | |
|    public History(String n) {
 | |
|       name = n;
 | |
|    }
 | |
| 
 | |
|    public String getName() {
 | |
|       return name;
 | |
|    }
 | |
| 
 | |
|    HistRow findRow(String n) {
 | |
|       //System.out.println("findCsv, n: " + n);
 | |
|       return csvh.get(n);
 | |
|    }
 | |
| 
 | |
|    void addRow(HistRow r) {
 | |
|       csv.add(r);
 | |
|       csvh.put(r.getName(), r);
 | |
|    }
 | |
| }
 | |
| 
 | |
| /** A Row represents a single KPI csv data point.  The csv is split into tokens
 | |
|  * for easier manipulation by other code.
 | |
|  */
 | |
| class Row {
 | |
|    Vector<String> rdata = new Vector();
 | |
|    String short_desc_key = null;
 | |
| 
 | |
|    String getNotes() {
 | |
|       return rdata.elementAt(kpi.NOTES_IDX);
 | |
|    }
 | |
| 
 | |
|    String getSubtestPassed() {
 | |
|       if (rdata.size() > kpi.SUBTEST_PASS_IDX)
 | |
|          return rdata.elementAt(kpi.SUBTEST_PASS_IDX);
 | |
|       return "";
 | |
|    }
 | |
| 
 | |
|    String getSubtestFailed() {
 | |
|       if (rdata.size() > kpi.SUBTEST_FAIL_IDX)
 | |
|          return rdata.elementAt(kpi.SUBTEST_FAIL_IDX);
 | |
|       return "";
 | |
|    }
 | |
| 
 | |
|    String getUnits() {
 | |
|       try {
 | |
|          return rdata.elementAt(kpi.UNITS_IDX);
 | |
|       }
 | |
|       catch (Exception e) {
 | |
|          return "";
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    String getGraphGroup() {
 | |
|       try {
 | |
|          return rdata.elementAt(kpi.GRAPH_GROUP_IDX);
 | |
|       }
 | |
|       catch (Exception e) {
 | |
|          return "";
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    int getPriority() {
 | |
|       try {
 | |
|          return Long.valueOf(rdata.elementAt(kpi.PRIORITY_IDX)).intValue();
 | |
|       }
 | |
|       catch (Exception e) {
 | |
|          return 0;
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    String getPassFail() {
 | |
|       return rdata.elementAt(kpi.PASS_FAIL_IDX);
 | |
|    }
 | |
| 
 | |
|    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<rdata.size(); i++) {
 | |
|          sb.append("[" + i + "] == " + rdata.elementAt(i) + "  ");
 | |
|       }
 | |
|       return sb.toString();
 | |
|    }
 | |
| }
 | |
| 
 | |
| /** A test contains information on one executation of one test.  For instance,
 | |
|  * a wifi-capacity-test would be a single test.  It may create a KPI.csv file with
 | |
|  * multiple rows.  It may also have logs for this test run, and KPI graph images.
 | |
|  * A Run consists of multiple tests.
 | |
|  */
 | |
| class Test {
 | |
|    String name;
 | |
|    Vector<String> titles = null;
 | |
|    Vector<Row> data = new Vector();
 | |
|    Hashtable<String, String> descs = new Hashtable();
 | |
|    Vector<String> kpi_images = new Vector();
 | |
|    Vector<String> log_csv = new Vector();
 | |
|    int pass = 0;
 | |
|    int fail = 0;
 | |
| 
 | |
|    int log_bugs = 0;
 | |
|    int log_warnings = 0;
 | |
|    int log_crashes = 0;
 | |
|    int log_restarting = 0;
 | |
| 
 | |
|    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;
 | |
|    }
 | |
| 
 | |
|    public int getLogBugs() {
 | |
|       return log_bugs;
 | |
|    }
 | |
| 
 | |
|    public int getLogWarnings() {
 | |
|       return log_warnings;
 | |
|    }
 | |
| 
 | |
|    public int getLogCrashes() {
 | |
|       return log_crashes;
 | |
|    }
 | |
| 
 | |
|    public int getLogRestarting() {
 | |
|       return log_restarting;
 | |
|    }
 | |
| 
 | |
|    public String toString() {
 | |
|       return "Name: " + name;
 | |
|    }
 | |
| 
 | |
|    public int getPass() {
 | |
|       return pass;
 | |
|    }
 | |
| 
 | |
|    public int getFail() {
 | |
|       return fail;
 | |
|    }
 | |
| 
 | |
|    void addKpiImage(String s) {
 | |
|       kpi_images.add(s);
 | |
|    }
 | |
| 
 | |
|    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 addLogCsv(String l) {
 | |
|       log_csv.add(l);
 | |
|       try {
 | |
|          StringTokenizer st = new StringTokenizer(l, "\t");
 | |
|          String tok = st.nextToken();
 | |
|          if (tok.equals("FILE")) {
 | |
|             // title, ignore rest of this title
 | |
|             return;
 | |
|          }
 | |
|          log_bugs += Long.valueOf(st.nextToken());
 | |
|          log_warnings += Long.valueOf(st.nextToken());
 | |
|          log_crashes += Long.valueOf(st.nextToken());
 | |
|          log_restarting += Long.valueOf(st.nextToken());
 | |
|       }
 | |
|       catch (Exception e) {
 | |
|          e.printStackTrace();
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    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");
 | |
| 
 | |
|          String pf = row.getPassFail().toLowerCase();
 | |
|          if (pf.indexOf("pass") >= 0) {
 | |
|             pass++;
 | |
|          }
 | |
|          else if (pf.indexOf("fail") >= 0) {
 | |
|             fail++;
 | |
|          }
 | |
| 
 | |
|          String spass = row.getSubtestPassed();
 | |
|          try {
 | |
|             if (!spass.equals("")) {
 | |
|                pass += Long.valueOf(spass).longValue();
 | |
|             }
 | |
|          }
 | |
|          catch (Exception ee) {
 | |
|             ee.printStackTrace();
 | |
|          }
 | |
| 
 | |
|          String sfail = row.getSubtestFailed();
 | |
|          try {
 | |
|             if (!sfail.equals("")) {
 | |
|                fail += Long.valueOf(sfail).longValue();
 | |
|             }
 | |
|          }
 | |
|          catch (Exception ee) {
 | |
|             ee.printStackTrace();
 | |
|          }
 | |
| 
 | |
|          row.setShortDescKey(row.getShortDesc().replace(" ", "_"));
 | |
|          //System.out.println("Row: " + row);
 | |
|          descs.put(row.getShortDesc(), row.getShortDesc());
 | |
|       }
 | |
|    }//addline
 | |
| }//Test
 | |
| 
 | |
| 
 | |
| /** A Run is a collection of tests.  This class encompasses the entire regression test
 | |
|  * for a particular flavor of test (basic, fast, etc).
 | |
|  * The CI/CD process will create one or more Runs per build artifact per testbed.
 | |
|  */
 | |
| class Run {
 | |
|    String name;
 | |
|    Hashtable<String, Test> tests = new Hashtable();
 | |
|    Vector<Test> testsv = new Vector();
 | |
| 
 | |
|    public Run(String n) {
 | |
|       name = n;
 | |
|    }
 | |
| 
 | |
|    public String toString() {
 | |
|       return "Name: " + name;
 | |
|    }
 | |
| 
 | |
|    int getPass() {
 | |
|       int pass = 0;
 | |
|       for (Test t: testsv) {
 | |
|          pass += t.getPass();
 | |
|       }
 | |
|       return pass;
 | |
|    }
 | |
| 
 | |
|    int getFail() {
 | |
|       int fail = 0;
 | |
|       for (Test t: testsv) {
 | |
|          fail += t.getFail();
 | |
|       }
 | |
|       return fail;
 | |
|    }
 | |
| 
 | |
|    int getLogBugs() {
 | |
|       int fail = 0;
 | |
|       for (Test t: testsv) {
 | |
|          fail += t.getLogBugs();
 | |
|       }
 | |
|       return fail;
 | |
|    }
 | |
| 
 | |
|    int getLogWarnings() {
 | |
|       int fail = 0;
 | |
|       for (Test t: testsv) {
 | |
|          fail += t.getLogWarnings();
 | |
|       }
 | |
|       return fail;
 | |
|    }
 | |
| 
 | |
|    int getLogCrashes() {
 | |
|       int fail = 0;
 | |
|       for (Test t: testsv) {
 | |
|          fail += t.getLogCrashes();
 | |
|       }
 | |
|       return fail;
 | |
|    }
 | |
| 
 | |
|    int getLogRestarting() {
 | |
|       int fail = 0;
 | |
|       for (Test t: testsv) {
 | |
|          fail += t.getLogRestarting();
 | |
|       }
 | |
|       return fail;
 | |
|    }
 | |
| 
 | |
|    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 getDutSerNum() {
 | |
|       Test t = getFirstTest();
 | |
|       if (t != null)
 | |
|          return t.getDutSerialNum();
 | |
|       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;
 | |
|       StringBuffer dbg = new StringBuffer();
 | |
|       dbg.append("Command: " + command);
 | |
|       if (args != null && args.length > 0) {
 | |
|          cmdArr = new String[1+args.length];
 | |
|          cmdArr[0] = command;
 | |
|          System.arraycopy(args, 0, cmdArr, 1, args.length);
 | |
|          for (int i = 0; i<args.length; i++) {
 | |
|             dbg.append(" " + args[i]);
 | |
|          }
 | |
|       } else {
 | |
|          cmdArr = new String[] { command };
 | |
|       }
 | |
| 
 | |
|       System.out.println("Running cmd: " + dbg.toString());
 | |
| 
 | |
|       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;
 | |
|       }
 | |
| 
 | |
|    }
 | |
| 
 | |
| }
 | 
