diff --git a/plugins/TestingList - Copy.java b/plugins/TestingList - Copy.java new file mode 100644 index 0000000..344a309 --- /dev/null +++ b/plugins/TestingList - Copy.java @@ -0,0 +1,2816 @@ +/* + * Copyright (c) 2015 Paul Scherrer Institute. All rights reserved. + */ +// + +import ch.psi.pshell.core.Context; +import ch.psi.pshell.scripting.StatementException; +import ch.psi.pshell.security.AccessLevel; +import ch.psi.pshell.ui.App; +import ch.psi.pshell.ui.Panel; +import ch.psi.pshell.ui.Plugin; +import ch.psi.pshell.ui.View; +import ch.psi.utils.Convert; +import ch.psi.utils.swing.SwingUtils; +import ch.psi.utils.swing.SwingUtils.OptionType; +import java.awt.Component; +import java.awt.Point; +import java.io.BufferedReader; +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.table.DefaultTableModel; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; +import java.util.function.Consumer; +import java.util.logging.FileHandler; +import java.util.logging.SimpleFormatter; +import java.util.regex.PatternSyntaxException; +import javax.script.ScriptException; +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JMenuItem; +import javax.swing.RowFilter; +import javax.swing.UIManager; +import javax.swing.filechooser.FileSystemView; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; +import org.apache.commons.io.FilenameUtils; +import org.python.core.PyList; +import static org.python.bouncycastle.util.Arrays.append; +import java.util.Collections; +// + +/** + * + * @author boccioli_m + */ +public class TestingList extends Panel { + Properties properties = new Properties(); + + + public TestingList() throws Exception { + initialise(); + } + +// + /** + * enumeration of table column indexes + */ + public enum COL { + + CHECK(0), + STARTSEQUENCE(1), + TIME(2), + DEVICENAME(3), + DEVICEPATH(4), + DEVICEDESCR(5), + TESTSUITE(6), + TESTNAME(7), + TESTPATH(8), + TESTPARAMS(9), + TESTDESCR(10), + TESTHELP(11), + RESULT(12), + STATUS(13), + ICON(14); + private int value; + + private COL(int value) { + this.value = value; + } + + /** + * + * @return int index of the corresponding column + */ + public int index() { + return (int) value; + } + }; + + /** + * enumeration of possible test statuses: text and related icon + */ + public enum TestStatus { + + SUCCESS, + FAILURE, + PENDING, + DISABLED, + RUNNING; + + /** + * + * @return + */ + public String IconFilename() { + String iconFileName = ""; + switch (this) { + case SUCCESS: + iconFileName = "/icons/run-ok-16px.png"; + break; + case FAILURE: + iconFileName = "/icons/run-error-16px.png"; + break; + case PENDING: + iconFileName = "/icons/run-stop-16px.png"; + break; + case DISABLED: + iconFileName = ""; + break; + case RUNNING: + iconFileName = "/icons/run-play-16px.png"; + break; + } + return iconFileName; + } + + @Override + public final String toString() { + String status = ""; + switch (this) { + case SUCCESS: + status = "Success"; + break; + case FAILURE: + status = "Failure"; + break; + case PENDING: + status = "Pending"; + break; + case DISABLED: + status = "Disabled"; + break; + case RUNNING: + status = "Running"; + break; + } + return status; + } + + /** + * + * @return ImageIcon corresponding to the selected testStatus + */ + public ImageIcon Icon() { + String iconFileName = this.IconFilename(); + ImageIcon icon = null; + if (iconFileName != "") { + icon = new ImageIcon(getClass().getResource(this.IconFilename())); + } + return icon; + } + }; + + /** + * Sequence options: AFTER: the test starts after the test above has + * finished TOGETHER: the test starts at the same time as the test above + */ + public enum StartSequence { + + AFTER, + TOGETHER; + + @Override + public final String toString() { + String status = ""; + switch (this) { + case AFTER: + status = "After previous"; + break; + case TOGETHER: + status = "With previous"; + break; + } + return status; + } + }; + + /** + * List of Keys defining the arguments to be passed to a test script + */ + public enum testArgNames { + + PARAMETERS, + TEST, + DEVICE, + TEST_PATH, + STATUS; + + @Override + public final String toString() { + String status = ""; + switch (this) { + case PARAMETERS: + status = "parameters"; + break; + case TEST: + status = "test"; + break; + case DEVICE: + status = "device"; + break; + case TEST_PATH: + status = "testPath"; + break; + case STATUS: + status = "status"; + break; + } + return status; + } + }; + + /** + * List of Keys defining the arguments to be passed to a test script + */ + public enum testPropertyNames { + + DEVICE_NAME, + DEVICE_DESCRIPTION, + TEST_NAME, + TEST_DESCRIPTION, + TEST_PARAMETERS, + TEST_HELP; + + @Override + public final String toString() { + String val = ""; + switch (this) { + case DEVICE_NAME: + case TEST_NAME: + val = "name"; + break; + case TEST_PARAMETERS: + val = "parameters"; + break; + case DEVICE_DESCRIPTION: + case TEST_DESCRIPTION: + val = "description"; + break; + case TEST_HELP: + val = "help"; + break; + } + return val; + } + }; +// + + Logger logger = Logger.getLogger("TestsLog"); + //these paths are converted to unix or win path according to host OS + public static Path TESTS_DEVICES_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "devices"); + public static Path TESTS_TESTS_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "tests"); + public static Path TESTS_CONFIG_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "config"); + public static Path TESTS_PROPERTIES_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "tests.properties"); + public final Path TESTS_LOG_DEFAULT_DIR = Paths.get(".", "home", "script", "tests", "log", "TestsLog" + getnow() + ".txt"); + public static String TESTS_CONFIG_FILENAME = ".config"; + public static String TESTS_HELP_FILENAME = "help.html"; + public static String VALUE_SEPARATOR = "&"; + public static String PARAM_SEPARATOR = ";"; + + + /** + * initialise panel + */ + private void initialise(){ + + /* + // testing RPS packets + System.out.println("msg:"); + int PORT1 = 0x8899; // this port + String mode = "2,IQCOM,$BMA1,1,DIA"; + int i = 0; + byte[] msg = new byte[128]; + msg[0] = 50; //bytecount + msg[2] = 105; // transfer function + msg[4] = (byte) PORT1; + msg[5] = (byte) (PORT1 >>> 8); + msg[6] = 1; // message id + msg[16] = 1; //io-func reset=2 read mode=0 write mode=1 + byte[] buffer = mode.getBytes(); + while (i < buffer.length) { + msg[28 + i] = buffer[i]; + i++; + } + for (i=0 ; i < msg.length; i++) { + System.out.print(String.format("%02X ", msg[i])); + } + System.out.println(""); + // end of testing RPS packets +*/ + + + + + + + + + initComponents(); + addIcons(); + initLogger(); + buildTable(); + + try { + loadTests(); + //if not administrator, then show only enabled tests + boolean bShow = getContext().getInstance().getLevel()==AccessLevel.administrator; + jCheckBoxMenuShowSelectedTests1.setEnabled(bShow); + } catch (Exception ex) { + getLogger().severe(ex.getMessage()); + } + loadProperties(); + + } + + + /** + * load general properties + */ + private void loadProperties(){ + File configFile = TESTS_PROPERTIES_DEFAULT_DIR.toFile(); + if (!configFile.isFile()) return; + boolean error = false; + try { + FileReader reader = new FileReader(configFile); + Properties props = new Properties(); + props.load(reader); + reader.close(); + String property; + properties = props; + + //custom panel + property = props.getProperty("customPanel"); + //System.out.println("load customPanel: " + property); + property = property.replace("\"",""); + loadCustomPanel(property); + + //list filter + property = props.getProperty("listFilter"); + //System.out.println("load listFilter: " + property); + if(property==null || property==""){ + loadListFilter(); + } else{ + property = property.replace("\"",""); + loadListFilter(Paths.get(TESTS_CONFIG_DEFAULT_DIR.toString(), property).toFile()); + } + + //show Enabled Tests Only + property = props.getProperty("showEnabledTestsOnly"); + //System.out.println("load showEnabledTestsOnly: " + property); + property = property.replace("\"",""); + showEnabledTestsOnly("true".equals(property)); + + + } catch (FileNotFoundException ex) { + // file does not exist + System.out.println(ex.toString()); + error = true; + } catch (IOException ex) { + // I/O error + System.out.println(ex.toString()); + error = true; + } catch (Exception ex){ + // Any other exception + System.out.println(ex.toString()); + error = true; + } + if(error){ + //load defaults + } + } + + + /** + * save general properties + */ + private void saveProperties(String key, String val){ + File configFile = TESTS_PROPERTIES_DEFAULT_DIR.toFile(); + + try { + if (!configFile.isFile()) configFile.createNewFile(); + FileReader reader = new FileReader(configFile); + System.out.println("save property: "+ key + " = " + val); + properties.setProperty(key, val); + Properties props = properties; + + OutputStream out = new FileOutputStream( configFile ); + props.store(out, "TestingList for pshell: configuration properties"); + + out.close(); + } catch (FileNotFoundException ex) { + // file does not exist + System.out.println(ex.toString()); + } catch (IOException ex) { + // I/O error + System.out.println(ex.toString()); + } + + } + + + /** + * close the custom panel if present + */ + private void closeCustomPanel(){ + jPanelCustomFrame.removeAll(); + jPanelCustom.setVisible(false); + repaint(); + //store custom panel in the properties + saveProperties("customPanel", ""); + } + + + /** + * load plugins available excluding the plugins used directly by TestingList + * @return list of plugins assumed to be custom panels + */ + private List getCustomPanels(){ + Path pluginsPath = Paths.get(".", "home", "config", "plugins.properties"); + List stringBuffer =new ArrayList() ; + try { + //get list of java classes from plugins list file + File file = pluginsPath.toFile(); + FileReader fileReader = new FileReader(file); + BufferedReader bufferedReader = new BufferedReader(fileReader); + String line, fileName; + while ((line = bufferedReader.readLine()) != null) { + if(line.contains("=enabled")){ + //extract java class name from file path + fileName = line.replace(".java=enabled", ""); + fileName = (Paths.get(fileName)).getFileName().toString(); + if( !(fileName.contains("TestingListDetails") || + fileName.contains("TestingList") || + fileName.contains("NewTest"))){ + stringBuffer.add(fileName); + } + } + } + fileReader.close(); + //System.out.println("Contents of file:"); + //System.out.println(stringBuffer.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + return stringBuffer; + } + + + /** + * get the presently active custom panel + * + * @return custom panel as component + */ + public Component getCustomPanel(){ + Component customPanel = null; + if(this.jPanelCustomFrame.getComponentCount() >0){ + Component components[] = this.jPanelCustomFrame.getComponents(); + //there is only one component + customPanel = components[0]; + } + return customPanel; + } + + + /** + * add custom panel if specified. + * Custom panels are java classes. To add a new custom panel MyNewPanel: + * - create a panel and save it as MyNewPanel.java + * - add MyNewPanel.java file in the pshell plugins folder + * - on pshell, open Plugins and enable MyNewPanel.java + * - restart pshell + * To show the new panel, open the menu Advanced/Load Custom Panel + * + * @param panel the panel to add as component + */ + public void loadCustomPanel(Component panel){ + if(panel != null) + loadCustomPanel(panel.getClass().getName() ); + else + closeCustomPanel(); + } + + /** + * add custom panel if specified. + * Custom panels are java classes. To add a new custom panel MyNewPanel: + * - create a panel and save it as MyNewPanel.java + * - add MyNewPanel.java file in the pshell plugins folder + * - on pshell, open Plugins and enable MyNewPanel.java + * - restart pshell + * To show the new panel, open the menu Advanced/Load Custom Panel + * + * @param sPanelClassName the panel to add as class name + */ + private void loadCustomPanel(String sPanelClassName){ + closeCustomPanel(); + if ( sPanelClassName == null || + sPanelClassName.trim() == "" || + sPanelClassName.isEmpty()) { + return; + } + + //if a custom panel is shown, the tests cannot be run in parallel, + //they can only be run in series (one after the other). + boolean changeSequenceToAfter = true;// = SwingUtils.OptionResult.No; + for (int row = 0; row < jTable1.getRowCount(); row++) { + try{ + if(jTable1.getValueAt(row, COL.STARTSEQUENCE.ordinal())==null) continue; + String sStartSequence = String.valueOf(jTable1.getValueAt(row, COL.STARTSEQUENCE.ordinal())); + if(sStartSequence.equals(StartSequence.TOGETHER.toString())){ + SwingUtils.OptionResult ret = SwingUtils.showOption(this, "Modify Start mode", + "A custom panel is active: tests can only run in sequence (Start mode: 'After previous'). "+ + "\nDo you want to keep the custom panel open and set all tests Start mode to 'After previous'?", + OptionType.YesNo); + if(ret == SwingUtils.OptionResult.Yes){ + changeSequenceToAfter = true ; + } else { + changeSequenceToAfter = false ; + } + break; + } + } catch (NullPointerException ex){ + continue; + } + } + //Set all active tests sequence to "After previous" + if(changeSequenceToAfter ){ + for (int row = 0; row < jTable1.getRowCount(); row++) { + boolean bSelected = (boolean) jTable1.getValueAt(row, COL.CHECK.ordinal()); + if(bSelected){ + jTable1.setValueAt(StartSequence.AFTER.toString(), row, COL.STARTSEQUENCE.ordinal()); + } + } + } else { //user does not wat to change running sequence from parallel to sequential + return; + } + + try { + //create a class to visualise the details panel + Class panelClass = getContext().getClassByName(sPanelClassName); + JPanel detailsPanel = (JPanel) panelClass.getConstructor(new Class[]{String.class}).newInstance(new Object[]{""}); + this.jPanelCustomFrame.add(detailsPanel); + this.jLabelCustomPanelName.setText("Custom panel: "+sPanelClassName); + repaint(); + revalidate(); + //store custom panel in the properties + saveProperties("customPanel", sPanelClassName); + jPanelCustom.setVisible(true); + animateCustomPanel(); + } catch (Exception ex) { + System.out.println("animateCustomPanel(): "+String.valueOf(ex)); + } + } + + /** + * Starts animating the custom panel, if present + * + * Note: the custom panel must have the public method "animate(String deviceName)" + * + * @param deviceName name of the device. The panel should then append the epics PV to the device name for caget/caset + */ + public void animateCustomPanel(String deviceName) { + try { + Component customPanel = getCustomPanel(); + //if no custom panel: nothing to do + if(customPanel==null) return; + //call the method "animate" of the custom panel (this function must be there) + Class[] cArg = new Class[1]; + cArg[0] = String.class; + Method animate = customPanel.getClass().getMethod("animate", cArg); + animate.invoke(customPanel, deviceName); + } catch (Exception ex) { + System.out.println("animateCustomPanel(): "+String.valueOf(ex)); + } + } + + + /** + * Starts animating the custom panel, if present, and only if the whole list of selected tests contains one only device name + * + * Note: the custom panel must have the public method "animate(String deviceName)" + */ + public void animateCustomPanel(){ + Component customPanel = getCustomPanel(); + //if no custom panel: nothing to do + if(customPanel==null) return; + //scan the table to see if only one device name is present + String sDeviceName = ""; + String sRowDeviceName = ""; + boolean bRowTestEnabled = false; + for (int row = 0; row < jTable1.getRowCount(); row++) { + sRowDeviceName = String.valueOf(jTable1.getValueAt(row, COL.DEVICENAME.ordinal())); + bRowTestEnabled = (boolean) jTable1.getValueAt(row, COL.CHECK.ordinal()); + if(bRowTestEnabled){ + if(sDeviceName == ""){ + sDeviceName = sRowDeviceName; + } else if(sDeviceName != sRowDeviceName){ + //there are at least two devices. Cannot animate the custom panel + return; + } + } + } + //if only one device name is present in the table, then animate the custom panel with the device + if(sDeviceName != ""){ + animateCustomPanel(sDeviceName); + } + } + + + /** + * write info into a log file + * @param text the info to be logged + */ + private void log(Object text) { + try { + getContext().getDataManager().appendLog(String.valueOf(text)); + } catch (Exception ex) { + System.out.println("animateCustomPanel(): "+String.valueOf(ex)); + } + } + + /** + * initialise the logger + */ + private void initLogger() { + /* + this.evalAsync("bla").handle((ok, ex) -> { + if (ex != null) { + + } else { + } + return ok; + }); + */ + + try { + + FileHandler fh; + // This block configure the logger with handler and formatter + fh = new FileHandler(TESTS_LOG_DEFAULT_DIR.toString()); + logger.addHandler(fh); + SimpleFormatter formatter = new SimpleFormatter(); + fh.setFormatter(formatter); + log("INF - " + "New testing session"); + } catch (SecurityException e) { + SwingUtils.showMessage(this, "initLogger()", e.toString()); + } catch (IOException e) { + SwingUtils.showMessage(this, "initLogger()", e.toString()); + } + } + + /** + * + * @throws IOException + */ + @SuppressWarnings("unchecked") + + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPopupMenuOptions = new javax.swing.JPopupMenu(); + jCheckBoxMenuShowSelectedTests = new javax.swing.JCheckBoxMenuItem(); + jMenuItemReload = new javax.swing.JMenuItem(); + jSeparator1 = new javax.swing.JPopupMenu.Separator(); + jMenuAdvanced = new javax.swing.JMenu(); + jMenuItemNewTest = new javax.swing.JMenuItem(); + jMenuItemNewDevice = new javax.swing.JMenuItem(); + jMenuItemEditScript = new javax.swing.JMenuItem(); + jSeparator6 = new javax.swing.JPopupMenu.Separator(); + jMenuLoadCustomPanel = new javax.swing.JMenu(); + jSeparator2 = new javax.swing.JPopupMenu.Separator(); + jMenuItemOpenLog = new javax.swing.JMenuItem(); + jPopupMenuConfigs = new javax.swing.JPopupMenu(); + jPopupMenuTable = new javax.swing.JPopupMenu(); + jMenuItemShowDetails = new javax.swing.JMenuItem(); + jSeparator5 = new javax.swing.JPopupMenu.Separator(); + jMenuItemRunSingleTest = new javax.swing.JMenuItem(); + jSeparator3 = new javax.swing.JPopupMenu.Separator(); + jMenuSelect = new javax.swing.JMenu(); + jMenuItemSelectAll = new javax.swing.JMenuItem(); + jMenuItemSelectSelection = new javax.swing.JMenuItem(); + jMenuItemSelectNone = new javax.swing.JMenuItem(); + jMenuItemDeselectSelection = new javax.swing.JMenuItem(); + jSeparator7 = new javax.swing.JPopupMenu.Separator(); + jMenuItemDeselect = new javax.swing.JMenuItem(); + jSeparator4 = new javax.swing.JPopupMenu.Separator(); + jCheckBoxMenuShowSelectedTests1 = new javax.swing.JCheckBoxMenuItem(); + jMenuItemReload1 = new javax.swing.JMenuItem(); + jPopupMenuCustom = new javax.swing.JPopupMenu(); + jMenuItemCustomClose = new javax.swing.JMenuItem(); + jPanel1 = new javax.swing.JPanel(); + jPanelTopCommands = new javax.swing.JPanel(); + jPanelButtons = new javax.swing.JPanel(); + jButtonOptions = new javax.swing.JButton(); + jButtonSave = new javax.swing.JButton(); + jButtonOpen = new javax.swing.JButton(); + jButtonRun = new javax.swing.JButton(); + jPanelSelection = new javax.swing.JPanel(); + jCheckBoxEnableDisable = new javax.swing.JCheckBox(); + jButtonMoveDown = new javax.swing.JButton(); + jButtonMoveUp = new javax.swing.JButton(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTable1 = new javax.swing.JTable(); + jPanelCustom = new javax.swing.JPanel(); + jPanelCustomHeader = new javax.swing.JPanel(); + jButtonX = new javax.swing.JButton(); + jLabelCustomPanelName = new javax.swing.JLabel(); + jPanelCustomFrame = new javax.swing.JPanel(); + + jCheckBoxMenuShowSelectedTests.setSelected(true); + jCheckBoxMenuShowSelectedTests.setText("Show enabled tests only"); + jCheckBoxMenuShowSelectedTests.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCheckBoxMenuShowSelectedTestsActionPerformed(evt); + } + }); + jPopupMenuOptions.add(jCheckBoxMenuShowSelectedTests); + + jMenuItemReload.setText("Reload tests"); + jMenuItemReload.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemReloadActionPerformed(evt); + } + }); + jPopupMenuOptions.add(jMenuItemReload); + jPopupMenuOptions.add(jSeparator1); + + jMenuAdvanced.setText("Advanced"); + + jMenuItemNewTest.setText("New Test..."); + jMenuItemNewTest.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemNewTestActionPerformed(evt); + } + }); + jMenuAdvanced.add(jMenuItemNewTest); + + jMenuItemNewDevice.setText("New Device..."); + jMenuItemNewDevice.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemNewDeviceActionPerformed(evt); + } + }); + jMenuAdvanced.add(jMenuItemNewDevice); + + jMenuItemEditScript.setText("Edit selected test"); + jMenuItemEditScript.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemEditScriptActionPerformed(evt); + } + }); + jMenuAdvanced.add(jMenuItemEditScript); + jMenuAdvanced.add(jSeparator6); + + jMenuLoadCustomPanel.setText("Load Custom Panel"); + jMenuLoadCustomPanel.addMenuListener(new javax.swing.event.MenuListener() { + public void menuCanceled(javax.swing.event.MenuEvent evt) { + } + public void menuDeselected(javax.swing.event.MenuEvent evt) { + } + public void menuSelected(javax.swing.event.MenuEvent evt) { + jMenuLoadCustomPanelMenuSelected(evt); + } + }); + jMenuAdvanced.add(jMenuLoadCustomPanel); + jMenuAdvanced.add(jSeparator2); + + jMenuItemOpenLog.setText("Open Log"); + jMenuItemOpenLog.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemOpenLogActionPerformed(evt); + } + }); + jMenuAdvanced.add(jMenuItemOpenLog); + + jPopupMenuOptions.add(jMenuAdvanced); + + jMenuItemShowDetails.setText("Open Test Details"); + jMenuItemShowDetails.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemShowDetailsActionPerformed(evt); + } + }); + jPopupMenuTable.add(jMenuItemShowDetails); + jPopupMenuTable.add(jSeparator5); + + jMenuItemRunSingleTest.setText("Run this test now"); + jMenuItemRunSingleTest.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemRunSingleTestActionPerformed(evt); + } + }); + jPopupMenuTable.add(jMenuItemRunSingleTest); + jPopupMenuTable.add(jSeparator3); + + jMenuSelect.setText("Enable/Disable"); + + jMenuItemSelectAll.setText("Enable all"); + jMenuItemSelectAll.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemSelectAllActionPerformed(evt); + } + }); + jMenuSelect.add(jMenuItemSelectAll); + + jMenuItemSelectSelection.setText("Enable selection"); + jMenuItemSelectSelection.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemSelectSelectionActionPerformed(evt); + } + }); + jMenuSelect.add(jMenuItemSelectSelection); + + jMenuItemSelectNone.setText("Disable all"); + jMenuItemSelectNone.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemSelectNoneActionPerformed(evt); + } + }); + jMenuSelect.add(jMenuItemSelectNone); + + jMenuItemDeselectSelection.setText("Disable selection"); + jMenuItemDeselectSelection.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemDeselectSelectionActionPerformed(evt); + } + }); + jMenuSelect.add(jMenuItemDeselectSelection); + jMenuSelect.add(jSeparator7); + + jMenuItemDeselect.setText("Deselect all"); + jMenuItemDeselect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemDeselectActionPerformed(evt); + } + }); + jMenuSelect.add(jMenuItemDeselect); + + jPopupMenuTable.add(jMenuSelect); + jPopupMenuTable.add(jSeparator4); + + jCheckBoxMenuShowSelectedTests1.setText("Show enabled tests only"); + jCheckBoxMenuShowSelectedTests1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCheckBoxMenuShowSelectedTests1ActionPerformed(evt); + } + }); + jPopupMenuTable.add(jCheckBoxMenuShowSelectedTests1); + + jMenuItemReload1.setText("Reload tests"); + jMenuItemReload1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemReload1ActionPerformed(evt); + } + }); + jPopupMenuTable.add(jMenuItemReload1); + + jMenuItemCustomClose.setText("Close this custom panel"); + jMenuItemCustomClose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jMenuItemCustomCloseActionPerformed(evt); + } + }); + jPopupMenuCustom.add(jMenuItemCustomClose); + + setLayout(new java.awt.BorderLayout()); + + jPanel1.setMinimumSize(new java.awt.Dimension(100, 200)); + jPanel1.setPreferredSize(new java.awt.Dimension(110, 110)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanelTopCommands.setMinimumSize(new java.awt.Dimension(115, 100)); + jPanelTopCommands.setLayout(new java.awt.BorderLayout()); + + jPanelButtons.setMinimumSize(new java.awt.Dimension(0, 80)); + jPanelButtons.setPreferredSize(new java.awt.Dimension(100, 80)); + jPanelButtons.setLayout(new java.awt.BorderLayout()); + + jButtonOptions.setToolTipText("More actions"); + jButtonOptions.setMaximumSize(new java.awt.Dimension(60, 40)); + jButtonOptions.setMinimumSize(new java.awt.Dimension(0, 40)); + jButtonOptions.setPreferredSize(new java.awt.Dimension(50, 40)); + jButtonOptions.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonOptionsActionPerformed(evt); + } + }); + jPanelButtons.add(jButtonOptions, java.awt.BorderLayout.LINE_START); + + jButtonSave.setToolTipText("Save current list of tests"); + jButtonSave.setMaximumSize(new java.awt.Dimension(60, 40)); + jButtonSave.setMinimumSize(new java.awt.Dimension(0, 40)); + jButtonSave.setPreferredSize(new java.awt.Dimension(50, 40)); + jButtonSave.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonSaveActionPerformed(evt); + } + }); + jPanelButtons.add(jButtonSave, java.awt.BorderLayout.LINE_END); + + jButtonOpen.setToolTipText("Open a list of tests"); + jButtonOpen.setMinimumSize(new java.awt.Dimension(0, 9)); + jButtonOpen.setPreferredSize(new java.awt.Dimension(33, 50)); + jButtonOpen.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonOpenActionPerformed(evt); + } + }); + jPanelButtons.add(jButtonOpen, java.awt.BorderLayout.PAGE_END); + + jPanelTopCommands.add(jPanelButtons, java.awt.BorderLayout.EAST); + + jButtonRun.setToolTipText("Run enabled tests"); + jButtonRun.setMaximumSize(new java.awt.Dimension(330000, 39)); + jButtonRun.setMinimumSize(new java.awt.Dimension(90, 90)); + jButtonRun.setPreferredSize(new java.awt.Dimension(90, 39)); + jButtonRun.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonRunActionPerformed(evt); + } + }); + jPanelTopCommands.add(jButtonRun, java.awt.BorderLayout.CENTER); + + jPanelSelection.setLayout(new java.awt.BorderLayout()); + + jCheckBoxEnableDisable.setToolTipText("Enable/Disable the selected tests"); + jCheckBoxEnableDisable.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jCheckBoxEnableDisable.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jCheckBoxEnableDisable.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCheckBoxEnableDisableActionPerformed(evt); + } + }); + jPanelSelection.add(jCheckBoxEnableDisable, java.awt.BorderLayout.WEST); + + jButtonMoveDown.setToolTipText("Move the selected tests down"); + jButtonMoveDown.setMaximumSize(new java.awt.Dimension(25, 25)); + jButtonMoveDown.setMinimumSize(new java.awt.Dimension(25, 25)); + jButtonMoveDown.setPreferredSize(new java.awt.Dimension(25, 25)); + jButtonMoveDown.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonMoveDownActionPerformed(evt); + } + }); + jPanelSelection.add(jButtonMoveDown, java.awt.BorderLayout.SOUTH); + + jButtonMoveUp.setToolTipText("Move the selected tests up"); + jButtonMoveUp.setMaximumSize(new java.awt.Dimension(25, 25)); + jButtonMoveUp.setMinimumSize(new java.awt.Dimension(25, 25)); + jButtonMoveUp.setPreferredSize(new java.awt.Dimension(25, 25)); + jButtonMoveUp.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonMoveUpActionPerformed(evt); + } + }); + jPanelSelection.add(jButtonMoveUp, java.awt.BorderLayout.PAGE_START); + + jPanelTopCommands.add(jPanelSelection, java.awt.BorderLayout.LINE_START); + + jPanel1.add(jPanelTopCommands, java.awt.BorderLayout.CENTER); + + add(jPanel1, java.awt.BorderLayout.NORTH); + + jTable1.setAutoCreateRowSorter(true); + jTable1.setFont(new java.awt.Font("Tahoma", 0, 15)); // NOI18N + jTable1.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Enable", "Start Mode", "Time", "Device Name", "Device Path", "Device Description", "Test Suite", "Test Name", "Test Peth", "Test Parameters", "Test Description", "Test Help", "Last Test Result", "Status", "" + } + ) { + Class[] types = new Class [] { + java.lang.Boolean.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, javax.swing.Icon.class + }; + boolean[] canEdit = new boolean [] { + true, true, false, false, false, false, false, false, false, false, false, false, false, false, false + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jTable1.getTableHeader().setReorderingAllowed(false); + jTable1.setDragEnabled(true); + jTable1.setRowHeight(22); + jTable1.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jTable1MouseClicked(evt); + } + }); + jTable1.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + jTable1KeyReleased(evt); + } + }); + jScrollPane2.setViewportView(jTable1); + + add(jScrollPane2, java.awt.BorderLayout.CENTER); + + jPanelCustom.setPreferredSize(new java.awt.Dimension(300, 100)); + + jPanelCustomHeader.setPreferredSize(new java.awt.Dimension(88, 20)); + jPanelCustomHeader.setLayout(new java.awt.BorderLayout()); + + jButtonX.setFont(new java.awt.Font("Tahoma", 0, 8)); // NOI18N + jButtonX.setToolTipText("Close this custom panel"); + jButtonX.setMaximumSize(new java.awt.Dimension(12, 12)); + jButtonX.setMinimumSize(new java.awt.Dimension(12, 12)); + jButtonX.setPreferredSize(new java.awt.Dimension(12, 12)); + jButtonX.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonXActionPerformed(evt); + } + }); + jPanelCustomHeader.add(jButtonX, java.awt.BorderLayout.EAST); + + jLabelCustomPanelName.setMaximumSize(new java.awt.Dimension(1000, 20)); + jLabelCustomPanelName.setMinimumSize(new java.awt.Dimension(100, 20)); + jLabelCustomPanelName.setPreferredSize(new java.awt.Dimension(100, 20)); + jLabelCustomPanelName.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + jLabelCustomPanelNameMouseClicked(evt); + } + }); + jPanelCustomHeader.add(jLabelCustomPanelName, java.awt.BorderLayout.CENTER); + + javax.swing.GroupLayout jPanelCustomLayout = new javax.swing.GroupLayout(jPanelCustom); + jPanelCustom.setLayout(jPanelCustomLayout); + jPanelCustomLayout.setHorizontalGroup( + jPanelCustomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelCustomLayout.createSequentialGroup() + .addGroup(jPanelCustomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanelCustomHeader, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE) + .addComponent(jPanelCustomFrame, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanelCustomLayout.setVerticalGroup( + jPanelCustomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelCustomLayout.createSequentialGroup() + .addComponent(jPanelCustomHeader, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanelCustomFrame, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanelCustom.setVisible(false); + + add(jPanelCustom, java.awt.BorderLayout.SOUTH); + }// //GEN-END:initComponents + + private void addIcons() { + jButtonRun.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/play-circled-64-000000.png"))); + jButtonOptions.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/listing-option-32px.png"))); + jButtonSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/android-save-24-000000.png"))); + jButtonOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/folder-open-36-000000.png"))); + jButtonMoveUp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/chevron-up-24-000000.png"))); + jButtonMoveDown.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/chevron-down-24-000000.png"))); + } + + private void jButtonRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRunActionPerformed + if (this.jButtonRun.getToolTipText().equals("Run enabled tests")) { + Object pshellStatus; + String sWait = "pshell is initialising: cannot start tests, please try again in a few seconds..."; + Boolean bWait = false; + //check if pshell is still initialising: if so, don't start the tests + try { + //invoke python method + pshellStatus = eval("get_context().state"); + if(String.valueOf(pshellStatus)=="Initializing"){ + bWait = true; + } + } catch (Exception ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + bWait = true; + } + //pshell is actually initialising: don't start tests + if(bWait){ + System.out.println(sWait); + return; + } + setButtonToStart(); + updateStatus(); + executeTests(); + } else { + try { + setToStopped(); + } catch (InterruptedException ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.WARNING, null, ex); + } + } + }//GEN-LAST:event_jButtonRunActionPerformed + + /** + * reaction to Stop + */ + private void setButtonToStop() throws InterruptedException { + abort(); + this.jButtonRun.setToolTipText("Run enabled tests"); + jButtonRun.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/play-circled-64-000000.png"))); + this.jTable1.setEnabled(true); + this.jButtonOpen.setEnabled(true); + this.jButtonOptions.setEnabled(true); + this.jButtonSave.setEnabled(true); + } + + /** + * reaction to Start + */ + private void setButtonToStart() { + this.jButtonRun.setToolTipText("Stop tests"); + jButtonRun.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/stop-circled-64-000000.png"))); + this.jTable1.clearSelection(); + this.jTable1.setEnabled(false); + this.jButtonOpen.setEnabled(false); + this.jButtonOptions.setEnabled(false); + this.jButtonSave.setEnabled(false); + } + + /** + * enable/disable the tests in the table. + * + * @param bEnable if true, enable. Else, disable + * @param onlyIfSelected if true, only the tests with Selected checkbox full will be enables/disabled. + * If false, all tests will be enabled/disabled + * @param smartEnable if true, it enables/disables selected tests or, if none selected, it enables/disables all + */ + private void enableAll(boolean bEnable, boolean onlyIfSelected, boolean smartEnable){ + int iSelRows = jTable1.getSelectedRowCount(); + + if (onlyIfSelected || (smartEnable && iSelRows > 0)) {// if some rows are selected, check/uncheck selected rows + for (int row = 0; row <= jTable1.getRowCount() - 1; row++) { + for (int selRow = 0; selRow <= jTable1.getSelectedRowCount() - 1; selRow++) { + if (row == jTable1.getSelectedRows()[selRow]) { + jTable1.setValueAt(bEnable, row, 0); + } + } + } + } else {//if none of the rows are selected, check/uncheck all + for (int row = 0; row <= jTable1.getRowCount() - 1; row++) { + jTable1.setValueAt(bEnable, row, 0); + } + } + updateStatus(); + } + + private void enableAll(boolean bEnable){ + enableAll(bEnable, false, false); + } + + private void enableSelection(boolean bEnable){ + enableAll(bEnable, true, true); + } + + private void jCheckBoxEnableDisableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxEnableDisableActionPerformed + enableAll(jCheckBoxEnableDisable.isSelected(), false, true); + }//GEN-LAST:event_jCheckBoxEnableDisableActionPerformed + + private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable1MouseClicked + if (this.jTable1.isEnabled()) { + if(evt.getButton() == java.awt.event.MouseEvent.BUTTON3){ + //right mouse click + //select row with right-click only if previously only one or zero rows were selected + if(jTable1.getSelectedRowCount()<2){ + Point cursor = evt.getPoint(); + int rowAtPoint = jTable1.rowAtPoint(cursor); + jTable1.setRowSelectionInterval(rowAtPoint, rowAtPoint); + } + //enable jMenuItemShowDetails depending on user privileges + this.jMenuItemShowDetails.setEnabled(Context.getInstance().getLevel()==AccessLevel.administrator); + //enable action Show Test Details only if one row is selected + this.jMenuItemShowDetails.setEnabled(jTable1.getSelectedRows().length == 1); + this.jMenuItemRunSingleTest.setEnabled(jTable1.getSelectedRows().length == 1); + jPopupMenuTable.show(jTable1, evt.getX(), evt.getY()); + } + else{ + //left mouse click + try { + switch (evt.getClickCount()) { + case 1: + break; + case 2: + openDetails(); + break; + } + //updateStatus(); + } catch (Exception ex) { + SwingUtils.showException(this, ex); + } + } + } + }//GEN-LAST:event_jTable1MouseClicked + + private void jTable1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTable1KeyReleased + updateStatus(); + }//GEN-LAST:event_jTable1KeyReleased + + private void jButtonMoveDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonMoveDownActionPerformed + moveDown(); + }//GEN-LAST:event_jButtonMoveDownActionPerformed + + private void jButtonMoveUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonMoveUpActionPerformed + moveUp(); + }//GEN-LAST:event_jButtonMoveUpActionPerformed + + private void jButtonOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOpenActionPerformed + this.loadListFilter(); + //this below is a test that can be useful to check that multithreading does work fine with passing variables + /* new Thread(() -> { + try { + //Object ret = eval("parallelize((run,('testLocalVar1',globals(),{'a':'21', 'b':34})), (run,('testLocalVar2',globals(),{'a':231, 'b':234})))"); + Object ret; + ret = eval("parallelize((run,('dummy',)))"); + ret = eval("parallelize((run,('testLocalVar1', None,{'a':21, 'b':34})), (run,('testLocalVar2', None, {'a':231, 'b':234})))"); + Object ret1 = ((ArrayList) ret).get(0); + Object ret2 = ((ArrayList) ret).get(1); + System.out.println(String.valueOf(ret1)); + System.out.println(String.valueOf(ret2)); + } catch (Exception ex) { + SwingUtils.showException(this, ex); + } + }).start(); + */ + }//GEN-LAST:event_jButtonOpenActionPerformed + + private void jButtonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveActionPerformed + saveSettings(); + }//GEN-LAST:event_jButtonSaveActionPerformed + + private void jButtonOptionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOptionsActionPerformed + //enable some menu items only for administrator access control level + this.jMenuItemEditScript.setVisible(Context.getInstance().getLevel()==AccessLevel.administrator); + this.jMenuItemNewTest.setVisible(Context.getInstance().getLevel()==AccessLevel.administrator); + this.jMenuItemNewDevice.setVisible(Context.getInstance().getLevel()==AccessLevel.administrator); + jPopupMenuOptions.show(jButtonOptions, 0, jButtonOptions.getHeight()); + }//GEN-LAST:event_jButtonOptionsActionPerformed + + private void jCheckBoxMenuShowSelectedTestsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuShowSelectedTestsActionPerformed + + boolean bShow = jCheckBoxMenuShowSelectedTests.getState(); + showEnabledTestsOnly(bShow); + jCheckBoxMenuShowSelectedTests1.setState(bShow); + }//GEN-LAST:event_jCheckBoxMenuShowSelectedTestsActionPerformed + + private void jMenuItemOpenLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOpenLogActionPerformed + + String cmd; + if (System.getProperty("os.name").toLowerCase().contains("windows")) { + cmd = "notepad.exe " + TESTS_LOG_DEFAULT_DIR; + } else { + cmd = "nedit " + TESTS_LOG_DEFAULT_DIR; + } + try { + Runtime.getRuntime().exec(cmd); + } catch (IOException ex) { + SwingUtils.showMessage(this, "jButtonOpenLogActionPerformed()", "jButtonOpenLogActionPerformed() " + ex.toString() + + " \nPlease open the file manually. \nFile dir: " + TESTS_LOG_DEFAULT_DIR); + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jMenuItemOpenLogActionPerformed + + private void jMenuItemReloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemReloadActionPerformed + + reloadTests(); + try { + cleanTests(); + cleanTests(); + } catch (IOException ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jMenuItemReloadActionPerformed + + private void jMenuItemNewTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemNewTestActionPerformed + + openNewTestEditor("Test"); + }//GEN-LAST:event_jMenuItemNewTestActionPerformed + + private void jMenuItemNewDeviceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemNewDeviceActionPerformed + + openNewTestEditor("Device"); + }//GEN-LAST:event_jMenuItemNewDeviceActionPerformed + + private void jCheckBoxMenuShowSelectedTests1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuShowSelectedTests1ActionPerformed + + boolean bShow = jCheckBoxMenuShowSelectedTests1.getState(); + showEnabledTestsOnly(bShow); + jCheckBoxMenuShowSelectedTests.setState(bShow); + }//GEN-LAST:event_jCheckBoxMenuShowSelectedTests1ActionPerformed + + private void jMenuItemReload1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemReload1ActionPerformed + + reloadTests(); + try { + cleanTests(); + cleanTests(); + } catch (IOException ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jMenuItemReload1ActionPerformed + + private void jMenuItemShowDetailsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemShowDetailsActionPerformed + try { + + openDetails(); + } catch (Exception ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jMenuItemShowDetailsActionPerformed + + private void jMenuItemSelectAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSelectAllActionPerformed + + enableAll(true); + }//GEN-LAST:event_jMenuItemSelectAllActionPerformed + + private void jMenuItemSelectNoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSelectNoneActionPerformed + + enableAll(false); + }//GEN-LAST:event_jMenuItemSelectNoneActionPerformed + + private void jMenuItemSelectSelectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSelectSelectionActionPerformed + + enableSelection(true); + }//GEN-LAST:event_jMenuItemSelectSelectionActionPerformed + + private void jMenuItemDeselectSelectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDeselectSelectionActionPerformed + + enableSelection(false); + }//GEN-LAST:event_jMenuItemDeselectSelectionActionPerformed + + private void jMenuItemEditScriptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemEditScriptActionPerformed + + int rows[] = jTable1.getSelectedRows(); + for(int row=0 ; row menuList = getCustomPanels(); + jMenuLoadCustomPanel.removeAll(); + for(int u = 0; u < menuList.size(); u++){ + + JMenuItem menuItem = new JMenuItem(menuList.get(u)); + menuItem.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + loadCustomPanel(((JMenuItem)evt.getSource()).getText()); + } + }); + jMenuLoadCustomPanel.add(menuItem); + } + }//GEN-LAST:event_jMenuLoadCustomPanelMenuSelected + + private void jButtonXActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonXActionPerformed + + closeCustomPanel(); + }//GEN-LAST:event_jButtonXActionPerformed + + private void jLabelCustomPanelNameMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelCustomPanelNameMouseClicked + + if(evt.getButton() == java.awt.event.MouseEvent.BUTTON3){ + //right mouse click + jPopupMenuCustom.show(jLabelCustomPanelName, evt.getX(), evt.getY()); + } + }//GEN-LAST:event_jLabelCustomPanelNameMouseClicked + + private void jMenuItemCustomCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCustomCloseActionPerformed + this.closeCustomPanel(); + }//GEN-LAST:event_jMenuItemCustomCloseActionPerformed + + private void jMenuItemDeselectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDeselectActionPerformed + + this.jTable1.clearSelection(); + }//GEN-LAST:event_jMenuItemDeselectActionPerformed + + // + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonMoveDown; + private javax.swing.JButton jButtonMoveUp; + private javax.swing.JButton jButtonOpen; + private javax.swing.JButton jButtonOptions; + private javax.swing.JButton jButtonRun; + private javax.swing.JButton jButtonSave; + private javax.swing.JButton jButtonX; + private javax.swing.JCheckBox jCheckBoxEnableDisable; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuShowSelectedTests; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuShowSelectedTests1; + private javax.swing.JLabel jLabelCustomPanelName; + private javax.swing.JMenu jMenuAdvanced; + private javax.swing.JMenuItem jMenuItemCustomClose; + private javax.swing.JMenuItem jMenuItemDeselect; + private javax.swing.JMenuItem jMenuItemDeselectSelection; + private javax.swing.JMenuItem jMenuItemEditScript; + private javax.swing.JMenuItem jMenuItemNewDevice; + private javax.swing.JMenuItem jMenuItemNewTest; + private javax.swing.JMenuItem jMenuItemOpenLog; + private javax.swing.JMenuItem jMenuItemReload; + private javax.swing.JMenuItem jMenuItemReload1; + private javax.swing.JMenuItem jMenuItemRunSingleTest; + private javax.swing.JMenuItem jMenuItemSelectAll; + private javax.swing.JMenuItem jMenuItemSelectNone; + private javax.swing.JMenuItem jMenuItemSelectSelection; + private javax.swing.JMenuItem jMenuItemShowDetails; + private javax.swing.JMenu jMenuLoadCustomPanel; + private javax.swing.JMenu jMenuSelect; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanelButtons; + private javax.swing.JPanel jPanelCustom; + private javax.swing.JPanel jPanelCustomFrame; + private javax.swing.JPanel jPanelCustomHeader; + private javax.swing.JPanel jPanelSelection; + private javax.swing.JPanel jPanelTopCommands; + private javax.swing.JPopupMenu jPopupMenuConfigs; + private javax.swing.JPopupMenu jPopupMenuCustom; + private javax.swing.JPopupMenu jPopupMenuOptions; + private javax.swing.JPopupMenu jPopupMenuTable; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JPopupMenu.Separator jSeparator1; + private javax.swing.JPopupMenu.Separator jSeparator2; + private javax.swing.JPopupMenu.Separator jSeparator3; + private javax.swing.JPopupMenu.Separator jSeparator4; + private javax.swing.JPopupMenu.Separator jSeparator5; + private javax.swing.JPopupMenu.Separator jSeparator6; + private javax.swing.JPopupMenu.Separator jSeparator7; + private javax.swing.JTable jTable1; + // End of variables declaration//GEN-END:variables + // + + /** + * reload tests from files + */ + public void reloadTests() { + try { + loadTests(); + } catch (IOException ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /** + * filter table: show only rows selected (checkbox checked) for running. + * + * @param show if false, show all tests. If true, show only selected tests. + */ + public void showEnabledTestsOnly(boolean show) { + String filter; + if (show) { + filter ="true"; + } else { + filter =""; + } + filterTests(filter); + //store filter in the properties + saveProperties("showEnabledTestsOnly", filter); + //if only enabled tests are visible, disable the move buttons + this.jButtonMoveUp.setEnabled(!show); + this.jButtonMoveDown.setEnabled(!show); + //check related checkboxes + jCheckBoxMenuShowSelectedTests.setSelected(show); + jCheckBoxMenuShowSelectedTests1.setSelected(show); + } + + /** + * open New Test/Device editor panel + * + * @param type can be "Device" or "Test". Either device or test will be created. + */ + public void openNewTestEditor(String type){ + try { + JDialog dlg = new JDialog(getView(), "New "+ type, true); + //create a class to visualise the details panel + Class testingListDetailsClass = getContext().getClassByName("NewTest"); + JPanel detailsPanel = (JPanel) testingListDetailsClass.getConstructor(new Class[]{String.class}).newInstance(new Object[]{type}); + dlg.getContentPane().add(detailsPanel); + dlg.pack(); + dlg.setVisible(true); + } catch (Exception ex) { + System.out.println("animateCustomPanel(): "+String.valueOf(ex)); + } + } + + /** + * filter table: show only rows containing the specified text. + * + * @param filterText text for filtering; can be a regex pattern. + */ + private void filterTests(String filterText) { + TableModel model = new DefaultTableModel() { + public Class getColumnClass(int column) { + Class returnValue; + if ((column >= 0) && (column < getColumnCount())) { + returnValue = getValueAt(0, column).getClass(); + } else { + returnValue = Object.class; + } + return returnValue; + } + }; + model = jTable1.getModel(); + + final TableRowSorter sorter = new TableRowSorter(model); + jTable1.setRowSorter(sorter); + if (filterText.length() == 0) { + sorter.setRowFilter(null); + } else { + try { + sorter.setRowFilter(RowFilter.regexFilter(filterText)); + } catch (PatternSyntaxException pse) { + System.err.println("Bad regex pattern"); + } + } + } + + /** + * return whether or not the tests can run (Run launched by the user) + * + * @return status of run button. True = tests launching sequence is running + */ + public boolean isTestRunAllowed() { + return (this.jButtonRun.getToolTipText().equals("Stop tests") && countPendingTests() > 0); + } + + /** + * move selected rows up in table + * + */ + private void moveUp() { + DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); + int[] rows = jTable1.getSelectedRows(); + try{ + if (rows[0] - 1 >= 0) { + jTable1.setAutoCreateRowSorter(false); + model.moveRow(rows[0], rows[rows.length - 1], rows[0] - 1); + jTable1.setAutoCreateRowSorter(true); + jTable1.setRowSelectionInterval(rows[0] - 1, rows[rows.length - 1] - 1); + } + } + catch(Exception ex){ + //fail silently + } + } + + /** + * move selected rows down in table + */ + private void moveDown() { + DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); + int[] rows = jTable1.getSelectedRows(); + try{ + if (rows[rows.length - 1] < jTable1.getRowCount()) { + jTable1.setAutoCreateRowSorter(false); + model.moveRow(rows[0], rows[rows.length - 1], rows[0] + 1); + jTable1.setAutoCreateRowSorter(true); + jTable1.setRowSelectionInterval(rows[0] + 1, rows[rows.length - 1] + 1); + } + } + catch(Exception ex){ + //fail silently + } + } + + /** + * open details of the selected row in a new panel + * + * @throws exception + */ + private void openDetails() throws Exception { + //pick details from the clicked row + int row = jTable1.getSelectedRow(); + String sDeviceName = jTable1.getValueAt(row, COL.DEVICENAME.ordinal()).toString(); + String sTestName = jTable1.getValueAt(row, COL.TESTNAME.ordinal()).toString(); + String sTestPath = jTable1.getValueAt(row, COL.TESTPATH.ordinal()).toString(); + String sTestCaseName = jTable1.getValueAt(row, COL.TESTSUITE.ordinal()).toString(); + String sTestDescription = getTestDescription(sTestPath); + String sDevicePath = jTable1.getValueAt(row, COL.DEVICEPATH.ordinal()).toString(); + System.out.println("sDevicePath: "+sDevicePath); + System.out.println("sTestPath: "+sTestPath); + String sDeviceDescription = jTable1.getValueAt(row, COL.DEVICEDESCR.ordinal()).toString(); + String sLastResult = jTable1.getValueAt(row, COL.RESULT.ordinal()).toString(); + String sResultTime = jTable1.getValueAt(row, COL.TIME.ordinal()).toString(); + String sTestHelp = String.valueOf(jTable1.getValueAt(row, COL.TESTHELP.ordinal())); + HashMap mParameters = getParameters(sTestPath, sDevicePath); + //create map for passing details to Details Panel + HashMap details = new HashMap(); + details.put("deviceName", sDeviceName); + details.put("deviceDescription", sDeviceDescription); + details.put("devicePath", sDevicePath); + details.put("testDescription", sTestDescription); + details.put("testSuite", sTestCaseName); + details.put("testName", sTestName); + details.put("testResult", sLastResult); + details.put("time", sResultTime); + details.put("parameters", mParameters); + details.put("testHelp", sTestHelp); + details.put("testPath", sTestPath); + //open details panel + JDialog dlg = new JDialog(getView(), "Test Details - " + sTestName, true); + //create a class to visualise the details panel + Class testingListDetailsClass = getContext().getClassByName("TestingListDetails"); + JPanel detailsPanel = (JPanel) testingListDetailsClass.getConstructor(new Class[]{HashMap.class}).newInstance(new Object[]{details}); + + dlg.getContentPane().add(detailsPanel); + //dlg.add(new TestingListDetails()); + dlg.pack(); + dlg.setVisible(true); + } + + /** + * open details of the selected row in a new panel + * + * @throws exception + */ + private void openListEditor() throws Exception { + + JDialog dlg = new JDialog(getView(), "Add/remove tests", true); + //create a class to visualise the edit panel + Class editTestingListClass = getContext().getClassByName("EditTestingList"); + JPanel detailsPanel = (JPanel) editTestingListClass.getConstructor(new Class[]{TableModel.class}).newInstance(jTable1.getModel()); + + dlg.getContentPane().add(detailsPanel); + //dlg.add(new TestingListDetails()); + dlg.pack(); + dlg.setVisible(true); + } + + + /** + * put the test result in table + * + * @param deviceName name of the device to search in table + * @param testPath path of the test to search in table + * @param res String result returned by the test + * @param status String status returned by the test + * @return int index of the row of the device in table + */ + public int showResult(String deviceName, String testPath, String res, String status) throws InterruptedException { + int rowD = -1; + testPath = testPath.replace("\\\\", "\\"); + String sTestName = testPath; + //getContext().getDataManager().appendLog(str(log)); + + //System.out.println("Looking for: deviceName: " + deviceName + "; testPath: " + testPath + " in table."); + + String sStatus; + if (status == "true") { + sStatus = TestStatus.SUCCESS.toString(); + } else if (status == "false") { + sStatus = TestStatus.FAILURE.toString(); + } else { + sStatus = status; + } + //search for device name in table + for (int row = 0; row <= jTable1.getRowCount() - 1; row++) { + if (deviceName.equals(jTable1.getValueAt(row, COL.DEVICENAME.ordinal())) + && testPath.equals(String.valueOf(jTable1.getValueAt(row, COL.TESTPATH.ordinal())).replace("\\", File.separator))) { + rowD = row; + sTestName = jTable1.getValueAt(rowD, COL.TESTNAME.ordinal()).toString(); + break; + } + } + ImageIcon icon = new ImageIcon(); + switch (sStatus) { + case "Success": + icon = TestStatus.SUCCESS.Icon(); + logger.log(Level.INFO, sStatus + " - Device: " + deviceName + "; Test: " + sTestName + "; Result: " + res); + log("INF - " + sStatus + " - Device: " + deviceName + "; Test: " + sTestName + "; Result: " + res); + break; + case "Failure": + icon = TestStatus.FAILURE.Icon(); + logger.log(Level.SEVERE, sStatus + " - Device: " + deviceName + "; Test: " + sTestName + "; Result: " + res); + break; + case "Running": + icon = TestStatus.RUNNING.Icon(); + //logger.log(Level.INFO, "Running Test: " + sTestName + "."); + break; + } + if (rowD >= 0) { + jTable1.setValueAt(icon, rowD, COL.ICON.ordinal()); + jTable1.setValueAt(getNow(), rowD, COL.TIME.ordinal()); + jTable1.setValueAt(res, rowD, COL.RESULT.ordinal()); + jTable1.setValueAt(sStatus, rowD, COL.STATUS.ordinal()); + } else { + logger.log(Level.SEVERE, "Cant find Test: " + testPath + " in table."); + } + //check if there are still pending tests. If not, set the status of the tool to Stopped. + if (countPendingTests() == 0 && countRunningTests() == 0) { + setToStopped(); + } + updateResultSummary(); + return rowD; + } + + /** + * show a summary icon indicating if all tests succeeded + * or if at least one failed + */ + public void updateResultSummary() { + ImageIcon summaryIcon = null; + if(countRunningTests()>0){ + summaryIcon = TestStatus.RUNNING.Icon(); + } else if(countFailureTests()>0){ + summaryIcon = TestStatus.FAILURE.Icon(); + } else if(countSuccessTests()>0){ + summaryIcon = TestStatus.SUCCESS.Icon(); + } + //System.out.println("successful: "+countSuccessTests() + " Failed: "+countSuccessTests() ); + setIcon(jTable1, COL.ICON.ordinal(), summaryIcon, ""); + } + + /** + * return the amount of tests currently in Pending state + * + * @return int counter of pending tests + */ + public int countPendingTests() { + return testsStatusCount(TestStatus.PENDING); + } + + /** + * return the amount of tests currently in Running state + * + * @return int counter of running tests + */ + public int countRunningTests() { + return testsStatusCount(TestStatus.RUNNING); + } + + /** + * return the amount of tests currently in Success state + * + * @return int counter of successful tests + */ + public int countSuccessTests() { + return testsStatusCount(TestStatus.SUCCESS); + } + + /** + * return the amount of tests currently in Failure state + * + * @return int counter of failed tests + */ + public int countFailureTests() { + return testsStatusCount(TestStatus.FAILURE); + } + + /** + * returns the amount of tests currently in "status" state + * + * @param status type of status to count + * @return int counter with occurrences of the status + */ + private int testsStatusCount(TestStatus status) { + String sStatus; + boolean bSelected; + int iTestsCount = 0; + for (int row = 0; row < jTable1.getRowCount(); row++) { + bSelected = (boolean) jTable1.getValueAt(row, COL.CHECK.ordinal()); + sStatus = jTable1.getValueAt(row, COL.STATUS.ordinal()).toString(); + //System.out.println("sStatus: " +sStatus); + if (bSelected && sStatus.equals(status.toString())) { + iTestsCount++; + } + } + return iTestsCount; + } + + /** + * set the tests to stopped + */ + private void setToStopped() throws InterruptedException { + //No more tests to play. Stop + setButtonToStop(); + logger.log(Level.INFO, "End of tests."); + } + + /** + * get the first test currently in progress + * + * @return properties of the test in progress: {deviceName,testPath} + */ + public String[] getTestInProgress() { + String[] dsTestProperties = {"", ""}; + //search for device name in table + try { + for (int row = 0; row <= jTable1.getRowCount() - 1; row++) { + if (jTable1.getValueAt(row, COL.STATUS.ordinal()).toString().equals(TestStatus.RUNNING.toString())) { + dsTestProperties[0] = jTable1.getValueAt(row, COL.DEVICENAME.ordinal()).toString(); + dsTestProperties[1] = jTable1.getValueAt(row, COL.TESTPATH.ordinal()).toString().replace("\\", File.separator); + break; + } + } + } catch (Exception ex) { + this.setToStopped(); + SwingUtils.showMessage(this, "getTestInProgress()", ex.toString()); + } finally { + return dsTestProperties; + } + } + + /** + * Stop all the tests in progress and return to idle state (no further tests are launched) + * + * @param resultMessage the message that will be shown as Result of each stopped test + */ + public void stopAll(String resultMessage) throws InterruptedException{ + setToStopped(); + String testInProgress[] = getTestInProgress(); + while(testInProgress[0]!=""){ + testInProgress = getTestInProgress(); + showResult(testInProgress[0], testInProgress[1], resultMessage, "false"); + } + try { + Object ret = eval("log('Tests interrupted by user')"); + } catch (Exception ex) { + System.out.println("animateCustomPanel(): "+String.valueOf(ex)); + } + } + + /** + * return the status of the specified test name for specified device name + * + * @param deviceName name of the device + * @param testPath path of the test file + * @return String containing the result returned by the test + */ + public String getResult(String deviceName, String testPath) { + String sStatus = ""; + int rowD = -1, colT = -1; + //search for device name in table + for (int row = 0; row <= jTable1.getRowCount() - 1; row++) { + if (deviceName.equals(jTable1.getValueAt(row, COL.DEVICENAME.ordinal()))) { + rowD = row; + break; + } + } + if (rowD >= 0) { + //search for test in table + if (testPath.equals(String.valueOf(jTable1.getValueAt(rowD, COL.TESTPATH.ordinal())).replace("\\", File.separator))) { + colT = COL.TESTNAME.ordinal(); + } + } + //get the test result + if (colT >= 0 && rowD >= 0) { + sStatus = jTable1.getValueAt(rowD, COL.STATUS.ordinal()).toString(); + } + return sStatus; + } + + /** + * visualise test status (columns status and icon) + */ + public void updateStatus() { + String sStatus; + boolean bSelected; + ImageIcon icon = null; + String sStart; + for (int row = 0; row <= jTable1.getRowCount() - 1; row++) { + bSelected = (boolean) jTable1.getValueAt(row, COL.CHECK.ordinal()); + sStart = String.valueOf(jTable1.getValueAt(row, COL.STARTSEQUENCE.ordinal())); + if (bSelected) { + sStatus = TestStatus.PENDING.toString(); + icon = TestStatus.PENDING.Icon(); + if (sStart == "") { + sStart = StartSequence.AFTER.toString(); + } + } else { + sStatus = TestStatus.DISABLED.toString(); + icon = TestStatus.DISABLED.Icon(); + sStart = ""; + } + jTable1.setValueAt(bSelected, row, COL.CHECK.ordinal()); + jTable1.setValueAt(icon, row, COL.ICON.ordinal()); + jTable1.setValueAt(sStatus, row, COL.STATUS.ordinal()); + jTable1.setValueAt(sStart, row, COL.STARTSEQUENCE.ordinal()); + } + updateResultSummary(); + } + + /** + * launch the execution of the tests + */ + public void executeTests() { + RunTest runTest = new RunTest(); + Thread t = new Thread(runTest); + t.start(); + } + + /** + * tests run multithreaded + */ + public class RunTest implements Runnable { + + private HashMap mParameters; + //private HashMap args; + private HashMap hTests ; + + /** + * + */ + public RunTest() { + //System.out.println("A0"); + } + + public void run() { + // code in the other thread, can reference "var" variable + loadCustomPanel(getCustomPanel()); + try { + executeTest(0); + } catch (InterruptedException ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.WARNING, null, ex); + } + } + + /** + * execute the selected tests in the list, starting from the position + * + * @param position row number from which to start executing tests + */ + private void executeTest(int position) throws InterruptedException { + boolean bSelected = false; + String sStartSequence, sStatus; + int[] selectedTestsRows = {}; + //scan through the table starting from 'position' and execute the first selected test found + int row = 0;// position; + if (row < jTable1.getRowCount()) { + for (row = position; row < jTable1.getRowCount(); row++) { + bSelected = (boolean) jTable1.getValueAt(row, COL.CHECK.ordinal()); + sStartSequence = jTable1.getValueAt(row, COL.STARTSEQUENCE.ordinal()).toString(); + sStatus = jTable1.getValueAt(row, COL.STATUS.ordinal()).toString(); + //collect tests to be launched in parallel + //the test must be: selected, set as start with previous, pending. + //alternatively, the test must be: selected, first of the list. + //System.out.println(String.valueOf(row) + "\t" + String.valueOf(bSelected) + "\t" + String.valueOf(selectedTestsRows.length) + "\t" + sStartSequence + "\t" + sStatus); + if (bSelected + && sStatus.equals(TestStatus.PENDING.toString()) + && (selectedTestsRows.length == 0 || //the test must be: selected, pending, first of the list. + sStartSequence.equals(StartSequence.TOGETHER.toString()))) { //or the test must be: selected, pending, set as start with previous + selectedTestsRows = append(selectedTestsRows, row); + } else if (bSelected + && sStatus.equals(TestStatus.PENDING.toString()) &&//if this test must be executed... + selectedTestsRows.length > 0 && //but there are already tests to be executed in parallel.... + (sStartSequence.equals(StartSequence.AFTER.toString()))) { //...and this test must be executed in series, then stop searching + break; + } + } + //if the user pressed Stop, or error, exit from run: + if(!isTestRunAllowed()) + return; + if (selectedTestsRows.length > 0) { //at least one test is selected: launch it (or them) + System.out.println("\n===================================================\n"); + executeParallelTestsGroup(selectedTestsRows); //last execution did not find a test file. Continue with next execution + executeTest(position + 1); + } else {//no tests were selected. end. + setToStopped(); + } + } + } + + /** + * build a HashMap containing the items picked from a specific table row. + * + * @param row the row whose items will fill the HashMap + * @return the HashMap containing the items picked from the specified table row. + */ + private HashMap buildMapFromTableRow(int row) { + String sDeviceName = jTable1.getValueAt(row, COL.DEVICENAME.ordinal()).toString(); + String sDevicePath = jTable1.getValueAt(row, COL.DEVICEPATH.ordinal()).toString().replace("\\", File.separator); + String sTestName = jTable1.getValueAt(row, COL.TESTNAME.ordinal()).toString(); + String sTestPath = jTable1.getValueAt(row, COL.TESTPATH.ordinal()).toString().replace("\\", File.separator); +// HashMap mParameters = buildParametersMap(String.valueOf(jTable1.getValueAt(row, COL.TESTPARAMS.ordinal()))); + //get the parameters directly frm he config file + HashMap mParameters = getParameters(sTestPath, sDevicePath); + HashMap testArgs = new HashMap(); + System.out.println("mParameters: " + mParameters.toString()); + //args.put("ret", ""); + testArgs.put(testArgNames.PARAMETERS.toString(), mParameters); + testArgs.put(testArgNames.TEST.toString(), sTestName); + testArgs.put(testArgNames.DEVICE.toString(), sDeviceName); + testArgs.put(testArgNames.TEST_PATH.toString(), sTestPath); + testArgs.put(testArgNames.STATUS.toString(), false); + + return testArgs; + } + + /** + * convert HashMap string separators to python dictionary string + * separators + * + * @param sParameters string coming from HashMap conaining the list of + * parameters to be passed to the test script. Example: + * {repeatTimes={description="Repeat N times", value="1"}, + * midPoint={description="Middle point A", value="41.0"}, + * spanFromMidPoint={description="B steps around middle point A", + * value="2.0"}} + * @return string of dictionary in python syntax. This can be passed to + * the python test script. Example of output: + * {'repeatTimes':{'description':'Repeat N + * times','value':'1'},'midPoint':{'description':'Middle point + * A','value':'41.0'},'spanFromMidPoint':{'description':'B steps around + * middle point A','value':'2.0'} + */ + private String convertParametersMapToPythonMap(String sParameters) { + String sPythonParams = sParameters; + sPythonParams = sPythonParams.replace(", ", ","); + sPythonParams = sPythonParams.replace(" ,", ","); + sPythonParams = sPythonParams.replace("{{", "#@"); + sPythonParams = sPythonParams.replace("\"}}", "@#"); + sPythonParams = sPythonParams.replace("\"},", "@%#"); + sPythonParams = sPythonParams.replace(",{", "#%@"); + sPythonParams = sPythonParams.replace("={", "^%&"); + sPythonParams = sPythonParams.replace("=}", "&%^"); + sPythonParams = sPythonParams.replace("\",", "','"); + sPythonParams = sPythonParams.replace("{", "{'"); + sPythonParams = sPythonParams.replace("\"}", "'}"); + sPythonParams = sPythonParams.replace("=\"", "':'"); + sPythonParams = sPythonParams.replace("^%&", "':{'"); + sPythonParams = sPythonParams.replace("&%^", "'}:'"); + sPythonParams = sPythonParams.replace("#@", "{{'"); + sPythonParams = sPythonParams.replace("@#", "'}}"); + sPythonParams = sPythonParams.replace("@%#", "'},'"); + sPythonParams = sPythonParams.replace("#%@", "',{'"); + return sPythonParams; + } + + /** + * start all the tests in the array rowsToExecute. all tests in the + * listed row indexes will be started at the same time. + * + * @param rowsToExecute array of indexes relative to the test rows in + * the table. The indexes in the array will execute the test in + * corresponding row + * @return return value: 0 means ok, <0 means problem + */ + private int executeParallelTestsGroup(int[] rowsToExecute) throws InterruptedException { + // System.out.println("Rows = " + Convert.arrayToString(rowsToExecute, " - " , 10)); + hTests = new HashMap(); + int iRet = -1; + HashMap args2 = new HashMap(); //this is the global map that will contain one map per test. + HashMap testArgs; //this is the map for a test. + String sTestName = "", sDeviceName = "", sTestPath = "", sTestID = ""; //sTestID is the compination of device name + test path + for (int row : rowsToExecute) { + //System.out.println(String.valueOf(row) + "\t" + sDeviceName + "\t" + sTestName + "\t" + sTestCaseName + "\t" + String.valueOf(rowsToExecute.length)); + try { + testArgs = buildMapFromTableRow(row); + sTestName = (String) testArgs.get(testArgNames.TEST.toString()); + sTestPath = (String) testArgs.get(testArgNames.TEST_PATH.toString()); + sDeviceName = (String) testArgs.get(testArgNames.DEVICE.toString()); + mParameters = (HashMap) testArgs.get(testArgNames.PARAMETERS.toString()); + sTestID = sDeviceName+"|"+sTestPath; + File f = new File(sTestPath); + if (!f.exists() || f.isDirectory()) { + logger.log(Level.SEVERE, "Cannot find test script: " + sTestPath); + showResult(sDeviceName, sTestPath, "Cannot find test script: " + sTestPath, TestStatus.FAILURE.toString()); + hTests = args2; + continue; + } + //if the user pressed Stop, exit from run: + if(!isTestRunAllowed()) + return iRet; + showResult(sDeviceName, sTestPath, "Test running", TestStatus.RUNNING.toString()); + //launch the test + if (!mParameters.isEmpty()) { + String msg = "Running test '" + sTestName + "' for device '" + sDeviceName + "' with the following parameters: " + mParameters.toString(); + logger.log(Level.INFO, msg); + System.out.println(msg); + } else { + String msg = "Running Test '" + sTestName + "'. No parameters found."; + logger.log(Level.INFO, msg); + System.out.println(msg); + } + //System.out.println("sTestID: " + sTestID); + Object retargs = args2.put(sTestID, testArgs); + //System.out.println("retargs: " + retargs); + hTests = args2; + iRet = 0; + } catch (Exception ex) { + ex.printStackTrace(); + SwingUtils.showMessage(TestingList.this, "executeTest()", ex.toString()); + logger.log(Level.SEVERE, ex.toString()); + showResult(sDeviceName, sTestPath, ex.toString(), TestStatus.FAILURE.toString()); + setToStopped(); + } + } + // System.out.println(hTests); + try { + int iLastExecutedTestIndex = -1; + final String sParallelizeBegin = "(run,(str('"; + final String sParallelizeEnd = "'),))"; + String sParallelizeArguments; + try { + String sParallelizeCommand = "parallelize("; + int i = 0; + int iTotalEntries = hTests.entrySet().size(); + HashMap args = new HashMap(); + //System.out.println("hTests: "+hTests.entrySet().toString()); + if(hTests.isEmpty()) return iRet; + for (Map.Entry hTest : hTests.entrySet()) { + sTestPath = (String) hTest.getValue().get(testArgNames.TEST_PATH.toString()); + sTestPath = sTestPath.replace("\\", "\\\\"); + sParallelizeCommand = sParallelizeCommand + "(run,(str('" + sTestPath; + sParallelizeArguments = "None, {'parameters':" + convertParametersMapToPythonMap(hTest.getValue().get("parameters").toString()) + + ",'test':'" + hTest.getValue().get(testArgNames.TEST.toString()) + + "','device':'" + hTest.getValue().get(testArgNames.DEVICE.toString()) + + "','status':'" + hTest.getValue().get(testArgNames.STATUS.toString()) + "'}"; + sParallelizeCommand = sParallelizeCommand + "')," + sParallelizeArguments; + i++; + if (i < iTotalEntries) { + sParallelizeCommand = sParallelizeCommand + ")),"; //between each "run" command + } else { + sParallelizeCommand = sParallelizeCommand + ")))"; //very last part of command "parallelize" + } + } + //animate the custom panel (if present) + animateCustomPanel(sDeviceName); + //System.out.println("sParallelizeCommand: " +sParallelizeCommand); + //run test(s) + Object ret = eval(sParallelizeCommand); + //System.out.println(ret); + String sTestResult, sTestStatus; + if(ret == null){ + SwingUtils.showMessage(TestingList.this, "executeParallelTestsGroup()", "The test script(s) did not return any feedback."); + System.out.println("The test script(s) did not return any feedback."); + } + //scan through all return mappings of all run tests + for (Object oTestRet : (ArrayList) ret) { + //check if the mapping of the selected test has all expected return values + if (((List) oTestRet).size() >= 4) { + //extract return data of the current test + sTestPath = String.valueOf(((List) oTestRet).get(0)); + sDeviceName = String.valueOf(((List) oTestRet).get(1)); + sTestResult = String.valueOf(((List) oTestRet).get(2)); + sTestStatus = String.valueOf(((List) oTestRet).get(3)); + sTestID = sDeviceName+"|"+sTestPath; + //from the map of executed tests, get the test name (key is test path) + HashMap hTest = hTests.get(sTestID); + sTestName = String.valueOf(hTest.get(testArgNames.TEST.toString())); + } else { //problem, the test script does not return all the expected return values + String sErrorText = "Test " + sTestPath + " did not return all required return values"; + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, sErrorText); + SwingUtils.showMessage(TestingList.this, "executeParallelTestsGroup()", sErrorText); + System.out.println(String.valueOf(sErrorText)); + //try to fetch at least first element of returned map. If fails, it will go to catch + sTestID = String.valueOf(((List) oTestRet).get(0)); + sTestStatus = sErrorText; + sTestResult = "false"; + HashMap hTest = hTests.get(sTestID); + sDeviceName = String.valueOf(hTest.get(testArgNames.DEVICE.toString())); + sTestName = String.valueOf(hTest.get(testArgNames.TEST.toString())); + } + //System.out.println("Result: " + sDeviceName + "|" + sTestPath + "|" + sTestResult + "|" + sTestStatus); + iLastExecutedTestIndex = showResult(sDeviceName, sTestPath, sTestResult, sTestStatus); + } + } catch (StatementException intEx) { + intEx.printStackTrace(); + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, intEx); + System.out.println("User interrupted test! |"+ sDeviceName+"|"+ sTestPath+"|"+ String.valueOf(intEx)); + stopAll("Test stopped by user"); + //showResult(sDeviceName, sTestPath, "User interrupted test", "false"); + //setToStopped(); + } catch (ClassCastException ccex) { + ccex.printStackTrace(); + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ccex); + SwingUtils.showMessage(TestingList.this, "executeParallelTestsGroup()", ccex.toString()); + //System.out.println(String.valueOf(ccex)); + if (!sDeviceName.isEmpty()) { + showResult(sDeviceName, sTestPath, ccex.toString(), TestStatus.FAILURE.toString()); + } + }catch (Exception ex) { + ex.printStackTrace(); + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + SwingUtils.showMessage(TestingList.this, "executeParallelTestsGroup()", ex.toString()); + System.out.println(String.valueOf(ex)); + showResult(sDeviceName, sTestPath, ex.toString(), TestStatus.FAILURE.toString()); + } + } catch (Exception ex) { + ex.printStackTrace(); + SwingUtils.showMessage(TestingList.this, "executeParallelTestsGroup(), run thread", ex.toString()); + logger.log(Level.SEVERE, ex.toString()); + setToStopped(); + } + return iRet; + } + } + + /** + * table management (hide internal columns, size, etc) + */ + private void buildTable() { + String sDate = getNow(); + DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); + jTable1.setModel(model); + + //Set up the combo box editor for the Start Sequence cells. + JComboBox comboBox = new JComboBox(); + comboBox.addItem(StartSequence.AFTER.toString()); + comboBox.addItem(StartSequence.TOGETHER.toString()); + jTable1.getColumnModel().getColumn(COL.STARTSEQUENCE.ordinal()).setCellEditor(new DefaultCellEditor(comboBox)); + //Set up tool tips for the sequence cells. + DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); + renderer.setToolTipText("Click for options"); + jTable1.getColumnModel().getColumn(COL.STARTSEQUENCE.ordinal()).setCellRenderer(renderer); + jTable1.getColumnModel().getColumn(COL.STARTSEQUENCE.ordinal()).setPreferredWidth(130); + jTable1.getColumnModel().getColumn(COL.STARTSEQUENCE.ordinal()).setMaxWidth(130); + jTable1.getColumnModel().getColumn(COL.ICON.ordinal()).setMaxWidth(27); + jTable1.getColumnModel().getColumn(COL.CHECK.ordinal()).setMaxWidth(27); + jTable1.getColumnModel().getColumn(COL.DEVICENAME.ordinal()).setPreferredWidth(200); + jTable1.getColumnModel().getColumn(COL.DEVICENAME.ordinal()).setMaxWidth(200); + jTable1.getColumnModel().getColumn(COL.TESTNAME.ordinal()).setPreferredWidth(200); + jTable1.getColumnModel().getColumn(COL.TESTNAME.ordinal()).setMaxWidth(200); + jTable1.getColumnModel().getColumn(COL.TESTSUITE.ordinal()).setPreferredWidth(200); + jTable1.getColumnModel().getColumn(COL.TESTSUITE.ordinal()).setMaxWidth(200); + jTable1.getColumnModel().getColumn(COL.STATUS.ordinal()).setPreferredWidth(90); + jTable1.getColumnModel().getColumn(COL.STATUS.ordinal()).setMaxWidth(90); + jTable1.getColumnModel().getColumn(COL.TIME.ordinal()).setPreferredWidth(200); + jTable1.getColumnModel().getColumn(COL.TIME.ordinal()).setMaxWidth(200); + hideColumn(COL.DEVICEDESCR); + hideColumn(COL.DEVICEPATH); + hideColumn(COL.TESTPATH); + hideColumn(COL.TESTDESCR); + hideColumn(COL.TESTPARAMS); + hideColumn(COL.TESTHELP); + jTable1.setAutoCreateRowSorter(true); + updateStatus(); + } + + /** + * hide a specific column + * @param column column to hide + */ + private void hideColumn(COL column) { + jTable1.getColumnModel().getColumn(column.ordinal()).setMinWidth(0); + jTable1.getColumnModel().getColumn(column.ordinal()).setMaxWidth(0); + } + + /** + * append test info (see parameters) to table + * + * @param deviceName + * @param deviceDescription + * @param testSuite + * @param testName + * @param testParams string of parameters. See buildParametersMap() for + * details + * @param testDescription + * @param testHelp + * + */ + private void addToTable(String deviceName, + String deviceDescription, + String devicePath, + String testSuite, + String testName, + String testParams, + String testDescription, + String testPath, + String testHelp) { + String sDate = ""; + if (testName.equals("") || deviceName.equals("")) { + return; + } + try { + ImageIcon icon = null;// new ImageIcon(getClass().getResource("/icons/button_pause-16px.png")); + DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); + //String testPath = FilenameUtils.separatorsToSystem(TESTS_TESTS_DEFAULT_DIR + testSuite + "/" + testName + "/" + testName + ".py"); + String otestPath = Paths.get(TESTS_TESTS_DEFAULT_DIR.toString(), testSuite, testName, testName + ".py").toString(); + String odevicePath = Paths.get(TESTS_DEVICES_DEFAULT_DIR.toString(), deviceName, deviceName + ".config").toString(); + + System.out.println("Old Test Path = " + otestPath); + System.out.println("Old Dev Path = " + odevicePath); + + System.out.println("Test Path = " + testPath); + System.out.println("Dev Path = " + devicePath); + Object rowData[] = new Object[]{false, "", sDate, deviceName, devicePath, deviceDescription, testSuite, testName, testPath, testParams, testDescription, testHelp, "", "Pending", icon}; + //vedify that this test is not already in the table + int totalRows = model.getRowCount(); + boolean bTestAlreadyInTable = false; + for (int row = 0; row < totalRows; row++) { + bTestAlreadyInTable = (model.getValueAt(row, COL.DEVICENAME.ordinal()).toString().equals(deviceName) + && model.getValueAt(row, COL.TESTSUITE.ordinal()).toString().equals(testSuite) + && model.getValueAt(row, COL.TESTNAME.ordinal()).toString().equals(testName) + && model.getValueAt(row, COL.TESTPATH.ordinal()).toString().replace("\\", File.separator).equals(testPath)); + if (bTestAlreadyInTable) { + break; + } + } + if (!bTestAlreadyInTable) { + model.addRow(rowData); + } + } catch (Exception ex) { + ex.printStackTrace(); + SwingUtils.showMessage(this, "loadListFilter()", ex.toString()); + } + updateStatus(); + } + + /** + * get the current time in format like 2015/07/02 15:59:43 + * + * @return formatted time + */ + public String getNow() { + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + return dateFormat.format(date); + } + + /** + * get the current time in format like 20150702155943 + * + * @return time with sortable format + */ + public String getnow() { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + Date date = new Date(); + return dateFormat.format(date); + } + + /** + * scan tests directory, scan devices directory, search for their test cases + * and scan for tests. + * + * @throws FileNotFoundException + * @throws IOException + */ + public void loadTests() throws FileNotFoundException, IOException { + Properties propDevice = new Properties(); + Properties propTest = new Properties(); + //String fileName = TESTS_DEVICES_DEFAULT_DIR; + //File folder = new File(fileName); + File testsFolder = null; + String sTestName; + int iCounter = 0; + //search devices and their tests + //Scan the list of devices + //File[] listOfDevices = TESTS_DEVICES_DEFAULT_DIR.toFile().listFiles(); + List listOfDevices = new ArrayList(); + Collections.addAll(listOfDevices, listFilesAsArray(TESTS_DEVICES_DEFAULT_DIR.toFile(), true)); + + for (File deviceInList : listOfDevices) { + propDevice.clear(); + if (deviceInList.isFile()) { + } else if (deviceInList.isDirectory()) { + System.out.println("deviceInList:" + deviceInList.getPath()); + File configFile = new File(deviceInList.getPath() + FilenameUtils.separatorsToSystem("/" + TESTS_CONFIG_FILENAME)); + if (configFile.exists() && !configFile.isDirectory()) { + InputStream is = new FileInputStream(configFile); + propDevice.load(is); + is.close(); + //config of device was loaded. now load the config of each test belonging to the device + testsFolder = Paths.get(TESTS_TESTS_DEFAULT_DIR.toString(), propDevice.getProperty("tests")).toFile(); + if (testsFolder.exists() && testsFolder.isDirectory()) { + File[] listOfTests = testsFolder.listFiles(); + for (File testinList : listOfTests) { + propTest.clear(); + if (testinList.isDirectory()) { + configFile = new File(testinList.getPath() + FilenameUtils.separatorsToSystem("/" + TESTS_CONFIG_FILENAME)); + if (configFile.exists() && !configFile.isDirectory()) { + InputStream ist = new FileInputStream(configFile); + propTest.load(ist); + ist.close(); + addToTable(propDevice.getProperty("name"), + propDevice.getProperty("description"), + deviceInList.getPath(), + propDevice.getProperty("tests"), + propTest.getProperty("name"), + "", //test parameters + "", //test description + testinList.getPath(), + propTest.getProperty("help")); + iCounter++; + } + } + } + } + } + } + } + //showEnabledTestsOnly(jCheckBoxMenuShowSelectedTests1.getState()); + logger.log(Level.INFO, iCounter + " tests loaded."); + } + + +public static File[] listFilesAsArray(File directory, boolean recurse) +{ + Collection files = listFiles(directory, recurse); + File[] arr = new File[files.size()]; + return (File[]) files.toArray(arr); +} + +public static Collection listFiles(File directory, boolean recurse){ + // List of files / directories + Vector files = new Vector (); + // Get files / directories in the directory + File[] entries = directory.listFiles(); + // Go over entries + for (File entry : entries){ + + files.add(entry); + // If the file is a directory and the recurse flag + // is set, recurse into the directory + if (recurse && entry.isDirectory()){ + files.addAll(listFiles(entry, recurse)); + } + } + // Return collection of files + return files; +} + + /** + * scan tests table and see if tests/devices in the table still exist in directory. + * Remove from table the tests whose files do not exist in directories. + * + * @throws FileNotFoundException + * @throws IOException + */ + public void cleanTests() throws FileNotFoundException, IOException { + Properties propDevice = new Properties(); + Properties propTest = new Properties(); + //String fileName = TESTS_DEVICES_DEFAULT_DIR; + //File folder = new File(fileName); + File testsFolder = null; + String sTestName; + int iCounter = 0; + //search devices and their tests + //Scan the list of devices + File[] listOfDevices = TESTS_DEVICES_DEFAULT_DIR.toFile().listFiles(); + //collect all tests from files + List testsInDir = new ArrayList(); + List testDetails = new ArrayList(); + for (File deviceInList : listOfDevices) { + propDevice.clear(); + if (deviceInList.isDirectory()) { + File configFile = new File(deviceInList.getPath() + FilenameUtils.separatorsToSystem("/"+TESTS_CONFIG_FILENAME)); + if (configFile.exists() && !configFile.isDirectory()) { + InputStream is = new FileInputStream(configFile); + propDevice.load(is); + is.close(); + //config of device was loaded. now load the config of each test belonging to the device + testsFolder = Paths.get(TESTS_TESTS_DEFAULT_DIR.toString(), propDevice.getProperty("tests")).toFile(); + if (testsFolder.exists() && testsFolder.isDirectory()) { + File[] listOfTests = testsFolder.listFiles(); + for (File testinList : listOfTests) { + propTest.clear(); + if (testinList.isDirectory()) { + configFile = new File(testinList.getPath() + FilenameUtils.separatorsToSystem("/"+TESTS_CONFIG_FILENAME)); + if (configFile.exists() && !configFile.isDirectory()) { + InputStream ist = new FileInputStream(configFile); + propTest.load(ist); + ist.close(); + testDetails = new ArrayList(); + testDetails.add(propDevice.getProperty("name")); + testDetails.add(propDevice.getProperty("tests")); + testDetails.add(propTest.getProperty("name")); + iCounter++; + testsInDir.add(testDetails); + } + } + } + } + } + } + } + //now check each test in table, if it is present in directory + DefaultTableModel model = (DefaultTableModel) jTable1.getModel(); + int row; + boolean bTestAlreadyInTable = false; + String testSuiteTable, testSuiteDir; + String testNameTable, testNameDir; + String deviceNameTable, deviceNameDir; + String testPathTable, testPathDir; + int totalRows = model.getRowCount(); + //loop among the tests in the table + for (row = 0; row < totalRows; row++) { + bTestAlreadyInTable = false; + deviceNameTable = model.getValueAt(row, COL.DEVICENAME.ordinal()).toString(); + //testSuiteTable = model.getValueAt(row, COL.TESTSUITE.ordinal()).toString(); + //testNameTable = model.getValueAt(row, COL.TESTNAME.ordinal()).toString(); + testPathTable = model.getValueAt(row, COL.TESTPATH.ordinal()).toString().replace("\\", File.separator); + //loop to compare current test in table with all tests in directory + for (int i = 0; i < testsInDir.size(); i++) { + deviceNameDir = testsInDir.get(i).get(0).toString(); + testSuiteDir = testsInDir.get(i).get(1).toString(); + testNameDir = testsInDir.get(i).get(2).toString(); + testPathDir = Paths.get(TESTS_TESTS_DEFAULT_DIR.toString(), + testSuiteDir, testNameDir, testNameDir + ".py").toString(); + //check if the test files and device files corresponding to the current test row exist + bTestAlreadyInTable = (testPathDir.equals(testPathTable) && deviceNameDir.equals(deviceNameTable)); + if (bTestAlreadyInTable) { + break; + } + } + if (!bTestAlreadyInTable) { + //this test in table does not exist any more in the tests directory or in the device directory: remove + model.removeRow(row); + totalRows = model.getRowCount(); + row=0; + } + } + } + + /** + * Build a map with optional parameters to be passed to the testing script. + * The map is like this: parameters \_ name | \_ value | \_ description \_ + * name | \_ value | \_ description ... the name 'name' is the mapping key. + * 'value' and 'description' are constant mapping keys of a nested map. + * + * @param parametersString string containing the parameters. Syntax: + * name:value:description[;name:value:description;...] + */ + private HashMap buildParametersMap(String parametersString) { + HashMap mParameters = new HashMap(); // contains name and attributes + HashMap mParameterAttributes = new HashMap(); //contians value and description + String[] dsParameterAttributes = null; + String[] dsParameters = parametersString.split(PARAM_SEPARATOR); + for (String sParameter : dsParameters) { + dsParameterAttributes = sParameter.split(VALUE_SEPARATOR); + if (dsParameterAttributes.length > 2) { + mParameterAttributes = new HashMap(); + mParameterAttributes.put("value", (Object) dsParameterAttributes[1]); + mParameterAttributes.put("description", dsParameterAttributes[2]); + //add parameter name and attributes (value + description) + mParameters.put(dsParameterAttributes[0], mParameterAttributes); + System.out.println(dsParameterAttributes[0] + dsParameterAttributes[1] + dsParameterAttributes[2]); + } + } + return mParameters; + } + + /** + * get the parameters from the test config file + * + * @param sTestPath directory where the test files are (directory with the + * test name) + * @return HashMap of the test parameters. See buildParametersMap() for + * details. + */ + private HashMap getTestParameters(String sTestPath) { + String testParams = getConfigItem("parameters", sTestPath); + return buildParametersMap(testParams); + } + + + /** + * get the parameters from the test and device config file. + * the test config params are default params. if the same param name + * is also in the device config, it will override the test param. + * + * @param sTestPath directory where the test files are (directory with the + * test name) + * @param sdevicePath device config file path + * @return HashMap of the test parameters. See buildParametersMap() for + * details. + */ + private HashMap getParameters(String sTestPath, String sDevicePath) { + HashMap deviceParams = buildParametersMap(getConfigItem("parameters", sDevicePath)); + HashMap testParams = buildParametersMap(getConfigItem("parameters", sTestPath)); + HashMap params = new HashMap(); + if(deviceParams.isEmpty()){ + return testParams; + } + Iterator itD = deviceParams.entrySet().iterator(); + System.out.println("deviceParams: " + deviceParams.size()); + while (itD.hasNext()) { + Map.Entry pairD = (Map.Entry)itD.next(); + System.out.println(pairD.getKey() + " = " + pairD.getValue()); + params.putIfAbsent(pairD.getKey(), pairD.getValue()); + } + Iterator it = testParams.entrySet().iterator(); + System.out.println("testParams: " + testParams.size()); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry)it.next(); + System.out.println(pair.getKey() + " = " + pair.getValue()); + // add parameter only if not already on device parameters + params.putIfAbsent(pair.getKey(), pair.getValue()); + } + return params; + } + + /** + * Get the description of the test. + * + * @param sTestPath directory where the test files are (directory with the + * test name) + * @return test description + */ + private String getTestDescription(String sTestPath) { + return getConfigItem("description", sTestPath); + } + + /** + * generic function that get a configuration item of a test. + * + * @param sParameterName configuration item name to retrieve from the test + * @param sTestPath directory where the test files are (directory with the + * test name) + * @return value of the configuration item + */ + private String getConfigItem(String sParameterName, String sTestPath) { + Properties propTest = new Properties(); + File fileTest = new File(sTestPath); + File dirTest = fileTest.getParentFile(); + String testParams = ""; + if (dirTest.isDirectory()) { + File configFile = new File(dirTest.getPath() + FilenameUtils.separatorsToSystem("/"+TESTS_CONFIG_FILENAME)); + if (configFile.exists() && !configFile.isDirectory()) { + try { + InputStream ist = new FileInputStream(configFile); + propTest.load(ist); + ist.close(); + testParams = propTest.getProperty(sParameterName); + if (testParams == null) { + testParams = ""; + } + + } catch (IOException ex) { + Logger.getLogger(TestingList.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + return testParams; + } + + /** + * Save current setup in a file. The current position of table rows is also + * saved. + */ + public void saveSettings() { + if (!TESTS_CONFIG_DEFAULT_DIR.toFile().isDirectory()) { + boolean success = TESTS_CONFIG_DEFAULT_DIR.toFile().mkdirs(); + if (!success) { + // Directory creation failed + SwingUtils.showMessage(this, "saveSettings()", "Cannot create directory " + TESTS_CONFIG_DEFAULT_DIR.toString()); + } + } + JFileChooser fc = new JFileChooser(TESTS_CONFIG_DEFAULT_DIR.toFile()); + int returnVal = fc.showSaveDialog(this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + saveSettings(file); + } + } + + /** + * Save current setup in a file. The current position of table rows is also + * saved. + * + * @param file file containing the settings + */ + private void saveSettings(File file) { + DefaultTableModel tableModel = (DefaultTableModel) jTable1.getModel(); + try { + ObjectOutputStream out = new ObjectOutputStream( + new FileOutputStream(file)); + out.writeObject(tableModel.getDataVector()); + out.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /** + * Save current setup in a file. The current position of table rows is also + * saved. + */ + public void loadListFilter() { + final JFileChooser fc = new JFileChooser(); + fc.setCurrentDirectory(TESTS_CONFIG_DEFAULT_DIR.toFile()); + int returnVal = fc.showOpenDialog(this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + loadListFilter(file); + this.showEnabledTestsOnly(true); + } + } + + /** + * Load current setup from a file. The current position of table rows is + * also saved. + * + * @param file file containing the settings + */ + private void loadListFilter(File file) { + if (file == null || !file.isFile()){ + loadListFilter(); + //store current file in the properties + saveProperties("listFilter", ""); + return; + } + DefaultTableModel tableModel = (DefaultTableModel) jTable1.getModel(); + try { + ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); + Vector rowData = (Vector) in.readObject(); + Iterator itr = rowData.iterator(); + //clear table + tableModel.getDataVector().removeAllElements(); + tableModel.fireTableDataChanged(); + //rewrite table + while (itr.hasNext()) { + tableModel.addRow((Vector) itr.next()); + } + in.close(); + loadTests(); + //store current file in the properties + saveProperties("listFilter", file.getName()); + //try to animate the custom panel, if the tests list concerns only one device + animateCustomPanel(); + } catch (Exception ex) { + ex.printStackTrace(); + SwingUtils.showMessage(this, "loadListFilter()", ex.toString()); + } + } + + + + + /** + * for putting an icon and text to a table header + */ + public class iconRenderer extends DefaultTableCellRenderer{ + public Component getTableCellRendererComponent(javax.swing.JTable table, + Object obj,boolean isSelected, boolean hasFocus, int row, + int column) { + txtIcon i = (txtIcon)obj; + if (obj == i) { + setIcon(i.imageIcon); + setText(i.txt); + } + setBorder(UIManager.getBorder("TableHeader.cellBorder")); + setHorizontalAlignment(javax.swing.JLabel.CENTER); + return this; + } + } + /** + * for putting an icon and text to a table header + */ + public class txtIcon { + String txt; + ImageIcon imageIcon; + txtIcon(String text, ImageIcon icon) { + txt = text; + imageIcon = icon; + } + } + + /** + * put an icon and text to a table header + * + * @param table the table where the header is + * @param col_index column index of the table header where to put the icon + * @param icon the icon to put to the header + * @param name the text to put to the header + */ + public void setIcon(javax.swing.JTable table, int col_index, ImageIcon icon,String name){ + table.getTableHeader().getColumnModel().getColumn(col_index).setHeaderRenderer(new iconRenderer()); + table.getColumnModel().getColumn(col_index).setHeaderValue(new txtIcon(name, icon)); + table.updateUI(); + } + +} diff --git a/script/tests/tests.properties b/script/tests/tests.properties index c91d0f1..17c2a47 100644 --- a/script/tests/tests.properties +++ b/script/tests/tests.properties @@ -1,5 +1,5 @@ #TestingList for pshell: configuration properties -#Mon Dec 11 14:43:33 CET 2017 +#Mon Dec 11 14:52:26 CET 2017 customPanel= showEnabledTestsOnly=true listFilter=test-no-ioc