You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2016/03/18 22:15:16 UTC

svn commit: r1735683 - in /jmeter/trunk: src/core/org/apache/jmeter/gui/action/ src/core/org/apache/jmeter/resources/ src/core/org/apache/jmeter/threads/gui/ xdocs/

Author: pmouawad
Date: Fri Mar 18 21:15:16 2016
New Revision: 1735683

URL: http://svn.apache.org/viewvc?rev=1735683&view=rev
Log:
Bug 59197 - Thread Group : it should be possible to only run a single threadgroup or a selection of threadgroups with a popup menu
#resolve #170
https://github.com/apache/jmeter/pull/170/
Bugzilla Id: 59197

Modified:
    jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
    jmeter/trunk/src/core/org/apache/jmeter/gui/action/Start.java
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
    jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
    jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java?rev=1735683&r1=1735682&r2=1735683&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/ActionNames.java Fri Mar 18 21:15:16 2016
@@ -99,9 +99,9 @@ public final class ActionNames {
     public static final String QUICK_COMPONENT  = "quick_component"; // $NON-NLS-1$
     public static final String COLLAPSE         = "collapse"; // $NON-NLS-1$
     public static final String EXPAND           = "expand"; // $NON-NLS-1$
+    public static final String RUN_TG           = "run_tg"; // $NON-NLS-1$
+    public static final String RUN_TG_NO_TIMERS = "run_tg_no_timers"; // $NON-NLS-1$
 
     // Prevent instantiation
-    private ActionNames(){
-        
-    }
+    private ActionNames() {}
 }

Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/action/Start.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/Start.java?rev=1735683&r1=1735682&r2=1735683&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/action/Start.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/action/Start.java Fri Mar 18 21:15:16 2016
@@ -19,7 +19,10 @@
 package org.apache.jmeter.gui.action;
 
 import java.awt.event.ActionEvent;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 
 import javax.swing.JOptionPane;
@@ -30,15 +33,21 @@ import org.apache.jmeter.engine.Standard
 import org.apache.jmeter.engine.TreeCloner;
 import org.apache.jmeter.engine.TreeClonerNoTimer;
 import org.apache.jmeter.gui.GuiPackage;
+import org.apache.jmeter.gui.tree.JMeterTreeListener;
+import org.apache.jmeter.gui.tree.JMeterTreeNode;
+import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.TestPlan;
+import org.apache.jmeter.threads.AbstractThreadGroup;
 import org.apache.jmeter.timers.Timer;
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jorphan.collections.HashTree;
+import org.apache.jorphan.collections.ListedHashTree;
 import org.apache.jorphan.logging.LoggingManager;
 import org.apache.log.Logger;
 
 public class Start extends AbstractAction {
-    private static final Logger log = LoggingManager.getLoggerForClass();
+    
+    private static final Logger LOG = LoggingManager.getLoggerForClass();
 
     private static final Set<String> commands = new HashSet<>();
 
@@ -47,6 +56,8 @@ public class Start extends AbstractActio
         commands.add(ActionNames.ACTION_START_NO_TIMERS);
         commands.add(ActionNames.ACTION_STOP);
         commands.add(ActionNames.ACTION_SHUTDOWN);
+        commands.add(ActionNames.RUN_TG);
+        commands.add(ActionNames.RUN_TG_NO_TIMERS);
     }
 
     private StandardJMeterEngine engine;
@@ -77,17 +88,46 @@ public class Start extends AbstractActio
             startEngine(true);
         } else if (e.getActionCommand().equals(ActionNames.ACTION_STOP)) {
             if (engine != null) {
-                log.info("Stopping test");
+                LOG.info("Stopping test");
                 GuiPackage.getInstance().getMainFrame().showStoppingMessage("");
                 engine.stopTest();
             }
         } else if (e.getActionCommand().equals(ActionNames.ACTION_SHUTDOWN)) {
             if (engine != null) {
-                log.info("Shutting test down");
+                LOG.info("Shutting test down");
                 GuiPackage.getInstance().getMainFrame().showStoppingMessage("");
                 engine.askThreadsToStop();
             }
+        } else if (e.getActionCommand().equals(ActionNames.RUN_TG) 
+                || e.getActionCommand().equals(ActionNames.RUN_TG_NO_TIMERS)) {
+            popupShouldSave(e);
+            boolean noTimers = e.getActionCommand().equals(ActionNames.RUN_TG_NO_TIMERS);
+            JMeterTreeListener treeListener = GuiPackage.getInstance().getTreeListener();
+            JMeterTreeNode[] nodes = treeListener.getSelectedNodes();
+            nodes = Copy.keepOnlyAncestors(nodes);
+            AbstractThreadGroup[] tg = keepOnlyThreadGroups(nodes);
+            if(nodes.length > 0) {
+                startEngine(noTimers, tg);
+            }
+            else {
+                LOG.warn("No thread group selected the test will not be started");
+            }
+        } 
+    }
+
+    /**
+     * filter the nodes to keep only the thread group
+     * @param currentNodes jmeter tree nodes
+     * @return the thread groups
+     */
+    private AbstractThreadGroup[] keepOnlyThreadGroups(JMeterTreeNode[] currentNodes) {
+        List<AbstractThreadGroup> nodes = new ArrayList<>();
+        for (JMeterTreeNode jMeterTreeNode : currentNodes) {
+            if(jMeterTreeNode.getTestElement() instanceof AbstractThreadGroup) {
+                nodes.add((AbstractThreadGroup) jMeterTreeNode.getTestElement());
+            }
         }
+        return nodes.toArray(new AbstractThreadGroup[nodes.size()]);
     }
 
     /**
@@ -95,24 +135,87 @@ public class Start extends AbstractActio
      * @param ignoreTimer flag to ignore timers
      */
     private void startEngine(boolean ignoreTimer) {
+        startEngine(ignoreTimer, null);
+    }
+    
+    /**
+     * Start JMeter engine
+     * @param ignoreTimer flag to ignore timers
+     * @param threadGroupsToRun Array of AbstractThreadGroup to run
+     */
+    private void startEngine(boolean ignoreTimer, AbstractThreadGroup[] threadGroupsToRun) {
         GuiPackage gui = GuiPackage.getInstance();
         HashTree testTree = gui.getTreeModel().getTestPlan();
+        
         JMeter.convertSubTree(testTree);
+        if(threadGroupsToRun != null && threadGroupsToRun.length>0) {
+            removeThreadGroupsFromHashTree(testTree, threadGroupsToRun);
+        }
+        
         testTree.add(testTree.getArray()[0], gui.getMainFrame());
-        log.debug("test plan before cloning is running version: "
+        LOG.debug("test plan before cloning is running version: "
                 + ((TestPlan) testTree.getArray()[0]).isRunningVersion());
+        
         TreeCloner cloner = cloneTree(testTree, ignoreTimer);
+        
+        ListedHashTree clonedTree = cloner.getClonedTree();
         engine = new StandardJMeterEngine();
-        engine.configure(cloner.getClonedTree());
+        engine.configure(clonedTree);
         try {
             engine.runTest();
         } catch (JMeterEngineException e) {
             JOptionPane.showMessageDialog(gui.getMainFrame(), e.getMessage(), 
                     JMeterUtils.getResString("error_occurred"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$
         }
-        log.debug("test plan after cloning and running test is running version: "
+        LOG.debug("test plan after cloning and running test is running version: "
                 + ((TestPlan) testTree.getArray()[0]).isRunningVersion());
     }
+
+    /**
+     * Remove thread groups from testTree that are not in threadGroupsToKeep
+     * @param testTree {@link HashTree}
+     * @param threadGroupsToKeep Array of {@link AbstractThreadGroup} to keep
+     */
+    private void removeThreadGroupsFromHashTree(HashTree testTree, AbstractThreadGroup[] threadGroupsToKeep) {
+        LinkedList<Object> copyList = new LinkedList<>(testTree.list());
+        for (Object o  : copyList) {
+            TestElement item = (TestElement) o;
+            if (o instanceof AbstractThreadGroup) {
+                if (!isInThreadGroups(item, threadGroupsToKeep)) {
+                    // hack hack hack
+                    // due to the bug of equals / hashcode on AbstractTestElement
+                    // where 2 AbstractTestElement can be equals but have different hashcode
+                    try {
+                        item.setEnabled(false);
+                        testTree.remove(item);
+                    } finally {
+                        item.setEnabled(true);                        
+                    }
+                }
+                else {
+                    removeThreadGroupsFromHashTree(testTree.getTree(item), threadGroupsToKeep);
+                }
+            }
+            else {
+                removeThreadGroupsFromHashTree(testTree.getTree(item), threadGroupsToKeep);
+            }
+        }
+    }
+    
+    /**
+     * @param item {@link TestElement}
+     * @param threadGroups Array of {@link AbstractThreadGroup} 
+     * @return true if item is in threadGroups array
+     */
+    private boolean isInThreadGroups(TestElement item, AbstractThreadGroup[] threadGroups) {
+        for (AbstractThreadGroup abstractThreadGroup : threadGroups) {
+            if(item == abstractThreadGroup) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
     
     /**
      * Create a Cloner that ignores {@link Timer} if removeTimers is true

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1735683&r1=1735682&r2=1735683&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Fri Mar 18 21:15:16 2016
@@ -893,6 +893,8 @@ revert_project?=Revert project?
 root=Root
 root_title=Root
 run=Run
+run_threadgroup=Start
+run_threadgroup_no_timers=Start no pauses
 running_test=Running test
 runtime_controller_title=Runtime Controller
 runtime_seconds=Runtime (seconds)

Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1735683&r1=1735682&r2=1735683&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Fri Mar 18 21:15:16 2016
@@ -878,6 +878,8 @@ revert_project?=Annuler les changements
 root=Racine
 root_title=Racine
 run=Lancer
+run_threadgroup=Lancer
+run_threadgroup_no_timers=Lancer sans pauses
 running_test=Lancer test
 runtime_controller_title=Contr\u00F4leur Dur\u00E9e d'ex\u00E9cution
 runtime_seconds=Temps d'ex\u00E9cution (secondes) \:

Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java?rev=1735683&r1=1735682&r2=1735683&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/threads/gui/AbstractThreadGroupGui.java Fri Mar 18 21:15:16 2016
@@ -22,16 +22,18 @@ import java.awt.BorderLayout;
 import java.awt.Dimension;
 import java.util.Arrays;
 import java.util.Collection;
+
 import javax.swing.BorderFactory;
 import javax.swing.Box;
 import javax.swing.ButtonGroup;
+import javax.swing.JMenuItem;
 import javax.swing.JPanel;
-
 import javax.swing.JPopupMenu;
 import javax.swing.JRadioButton;
 
 import org.apache.jmeter.gui.AbstractJMeterGuiComponent;
 import org.apache.jmeter.gui.action.ActionNames;
+import org.apache.jmeter.gui.action.ActionRouter;
 import org.apache.jmeter.gui.util.MenuFactory;
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.testelement.property.StringProperty;
@@ -78,6 +80,22 @@ public abstract class AbstractThreadGrou
                 },
                 JMeterUtils.getResString("add"), // $NON-NLS-1$
                 ActionNames.ADD));
+        
+        if(this.isEnabled()) {
+            pop.addSeparator();
+            JMenuItem runTg = new JMenuItem(JMeterUtils.getResString("run_threadgroup"));
+            runTg.setName("run_threadgroup");
+            runTg.addActionListener(ActionRouter.getInstance());
+            runTg.setActionCommand(ActionNames.RUN_TG);
+            pop.add(runTg);
+    
+            JMenuItem runTgNotimers = new JMenuItem(JMeterUtils.getResString("run_threadgroup_no_timers"));
+            runTgNotimers.setName("run_threadgroup_no_timers");
+            runTgNotimers.addActionListener(ActionRouter.getInstance());
+            runTgNotimers.setActionCommand(ActionNames.RUN_TG_NO_TIMERS);
+            pop.add(runTgNotimers);
+        }
+        
         MenuFactory.addEditMenu(pop, true);
         MenuFactory.addFileMenu(pop, false);
         return pop;

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1735683&r1=1735682&r2=1735683&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Fri Mar 18 21:15:16 2016
@@ -275,6 +275,7 @@ Summary
 <li><bug>58426</bug>Improve display of JMeter on high resolution devices (HiDPI) (part 1 of enhancement)</li>
 <li><bug>59105</bug>TableEditor : Add ability to paste rows from clipboard and delete multiple selection. Contributed by Vincent Herilier (vherilier at gmail.com)</li>
 <li><bug>59152</bug>Thread Group: Change "Action to be taken after a Sample Error" value from "Continue" to "Start Next thread loop". Contributed by Antonio Gomes Rodrigues (ra0077 at gmail.com)</li>
+<li><bug>59197</bug>Thread Group : it should be possible to only run a single threadgroup or a selection of threadgroups with a popup menu. Contributed by Benoit Wiart (benoit dot wiart at gmail.com)</li>
 </ul>
 <ch_section>Non-functional changes</ch_section>
 <ul>