Author: pmouawad
Date: Thu Mar 24 21:14:46 2016
New Revision: 1736508
URL: http://svn.apache.org/viewvc?rev=1736508&view=rev
Log:
Bug 58941 - Create a new Starter that runs thread groups in validation mode (1
thread only, 1 iteration, no pause all customizable)
Bugzilla Id: 58941
Added:
jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/
jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/TreeClonerForValidation.java
(with props)
Modified:
jmeter/trunk/bin/jmeter.properties
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/bin/jmeter.properties
URL:
http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1736508&r1=1736507&r2=1736508&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Thu Mar 24 21:14:46 2016
@@ -1304,3 +1304,24 @@ system.properties=system.properties
# Comma separated list of files that contain reference to templates and their
description
# Path must be relative to jmeter root folder
#template.files=/bin/templates/templates.xml
+
+
+#---------------------------------------------------------------------------
+# Thread Group Validation feature
+#---------------------------------------------------------------------------
+
+# Validation is the name of the feature used to rapidly validate a Thread
Group runs fine
+# Default implementation is
org.apache.jmeter.gui.action.validation.TreeClonerForValidation
+# It runs validation without timers, with 1 thread and 1 iteration
+# You can implement your own policy that must extend
org.apache.jmeter.engine.TreeCloner
+# JMeter will instanciate it and use it to create the Tree used to run
validation on Thread Group
+#testplan_validation.tree_cloner_class=org.apache.jmeter.gui.action.validation.TreeClonerForValidation
+
+# Number of threads to use to validate a Thread Group
+#testplan_validation.nb_threads_per_thread_group=1
+
+# Ignore timers when validating the thread group of plan
+#testplan_validation.ignore_timers=true
+
+# Number of iterations to use to validate a Thread Group
+#testplan_validation.number_iterations=1
\ No newline at end of file
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=1736508&r1=1736507&r2=1736508&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 Thu Mar
24 21:14:46 2016
@@ -101,6 +101,7 @@ public final class ActionNames {
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$
+ public static final String VALIDATE_TG = "validate_tg"; //$NON-NLS-1$
// Prevent instantiation
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=1736508&r1=1736507&r2=1736508&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 Thu Mar 24
21:14:46 2016
@@ -33,6 +33,7 @@ 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.action.validation.TreeClonerForValidation;
import org.apache.jmeter.gui.tree.JMeterTreeListener;
import org.apache.jmeter.gui.tree.JMeterTreeNode;
import org.apache.jmeter.testelement.TestElement;
@@ -45,12 +46,33 @@ import org.apache.jorphan.collections.Li
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
+/**
+ * Set of Actions to:
+ * <ul>
+ * <li>Start a Test Plan</li>
+ * <li>Start a Test Plan without sleeping on the timers</li>
+ * <li>Stop a Test Plan</li>
+ * <li>Shutdown a Test plan</li>
+ * <li>Run a set of Thread Groups</li>
+ * <li>Run a set of Thread Groups without sleeping on the timers</li>
+ * <li>Validate a set of Thread Groups with/without sleeping on the
timers depending on jmeter properties</li>
+ * </ul>
+ */
public class Start extends AbstractAction {
private static final Logger LOG = LoggingManager.getLoggerForClass();
private static final Set<String> commands = new HashSet<>();
+ private static final String VALIDATION_CLONER_CLASS_PROPERTY_NAME =
+ "testplan_validation.tree_cloner_class"; //$NON-NLS-1$
+ /**
+ * Implementation of {@link TreeCloner} used to clone the tree before
running validation
+ */
+ private static final String CLONER_FOR_VALIDATION_CLASS_NAME =
+ JMeterUtils.getPropDefault(VALIDATION_CLONER_CLASS_PROPERTY_NAME,
//$NON-NLS-1$
+ TreeClonerForValidation.class.getName());
+
static {
commands.add(ActionNames.ACTION_START);
commands.add(ActionNames.ACTION_START_NO_TIMERS);
@@ -58,6 +80,7 @@ public class Start extends AbstractActio
commands.add(ActionNames.ACTION_SHUTDOWN);
commands.add(ActionNames.RUN_TG);
commands.add(ActionNames.RUN_TG_NO_TIMERS);
+ commands.add(ActionNames.VALIDATE_TG);
}
private StandardJMeterEngine engine;
@@ -99,15 +122,18 @@ public class Start extends AbstractActio
engine.askThreadsToStop();
}
} else if (e.getActionCommand().equals(ActionNames.RUN_TG)
- || e.getActionCommand().equals(ActionNames.RUN_TG_NO_TIMERS)) {
+ || e.getActionCommand().equals(ActionNames.RUN_TG_NO_TIMERS)
+ || e.getActionCommand().equals(ActionNames.VALIDATE_TG)) {
popupShouldSave(e);
boolean noTimers =
e.getActionCommand().equals(ActionNames.RUN_TG_NO_TIMERS);
+ boolean isValidation =
e.getActionCommand().equals(ActionNames.VALIDATE_TG);
+
JMeterTreeListener treeListener =
GuiPackage.getInstance().getTreeListener();
JMeterTreeNode[] nodes = treeListener.getSelectedNodes();
nodes = Copy.keepOnlyAncestors(nodes);
AbstractThreadGroup[] tg = keepOnlyThreadGroups(nodes);
if(nodes.length > 0) {
- startEngine(noTimers, tg);
+ startEngine(noTimers, isValidation, tg);
}
else {
LOG.warn("No thread group selected the test will not be
started");
@@ -143,7 +169,20 @@ public class Start extends AbstractActio
* @param ignoreTimer flag to ignore timers
* @param threadGroupsToRun Array of AbstractThreadGroup to run
*/
- private void startEngine(boolean ignoreTimer, AbstractThreadGroup[]
threadGroupsToRun) {
+ private void startEngine(boolean ignoreTimer,
+ AbstractThreadGroup[] threadGroupsToRun) {
+ startEngine(ignoreTimer, false, threadGroupsToRun);
+ }
+
+ /**
+ * Start JMeter engine
+ * @param ignoreTimer flag to ignore timers
+ * @param isValidationShot
+ * @param threadGroupsToRun Array of AbstractThreadGroup to run
+ */
+ private void startEngine(boolean ignoreTimer,
+ boolean isValidationShot,
+ AbstractThreadGroup[] threadGroupsToRun) {
GuiPackage gui = GuiPackage.getInstance();
HashTree testTree = gui.getTreeModel().getTestPlan();
@@ -151,14 +190,19 @@ public class Start extends AbstractActio
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: "
+ ((TestPlan) testTree.getArray()[0]).isRunningVersion());
-
- TreeCloner cloner = cloneTree(testTree, ignoreTimer);
-
- ListedHashTree clonedTree = cloner.getClonedTree();
+
+ ListedHashTree clonedTree = null;
+ if(isValidationShot) {
+ TreeCloner cloner = createTreeClonerForValidation();
+ testTree.traverse(cloner);
+ clonedTree = cloner.getClonedTree();
+ } else {
+ TreeCloner cloner = cloneTree(testTree, ignoreTimer);
+ clonedTree = cloner.getClonedTree();
+ }
engine = new StandardJMeterEngine();
engine.configure(clonedTree);
try {
@@ -172,6 +216,23 @@ public class Start extends AbstractActio
}
/**
+ *
+ * @return {@link TreeCloner}
+ */
+ private static TreeCloner createTreeClonerForValidation() {
+ Class<?> clazz;
+ try {
+ clazz = Class.forName(CLONER_FOR_VALIDATION_CLASS_NAME, true,
Thread.currentThread().getContextClassLoader());
+ return (TreeCloner) clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException |
ClassNotFoundException ex) {
+ LOG.error("Error instanciating class:'"
+ +CLONER_FOR_VALIDATION_CLASS_NAME+"' defined in property
:'"
+ +VALIDATION_CLONER_CLASS_PROPERTY_NAME+"'", ex);
+ return new TreeClonerForValidation();
+ }
+ }
+
+ /**
* Remove thread groups from testTree that are not in threadGroupsToKeep
* @param testTree {@link HashTree}
* @param threadGroupsToKeep Array of {@link AbstractThreadGroup} to keep
Added:
jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/TreeClonerForValidation.java
URL:
http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/TreeClonerForValidation.java?rev=1736508&view=auto
==============================================================================
---
jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/TreeClonerForValidation.java
(added)
+++
jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/TreeClonerForValidation.java
Thu Mar 24 21:14:46 2016
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action.validation;
+
+import org.apache.jmeter.control.LoopController;
+import org.apache.jmeter.engine.TreeCloner;
+import org.apache.jmeter.threads.AbstractThreadGroup;
+import org.apache.jmeter.threads.ThreadGroup;
+import org.apache.jmeter.timers.Timer;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+/**
+ * Clones the test tree, skipping test elements that implement {@link Timer}
by default.
+ * @since 3.0
+ */
+public class TreeClonerForValidation extends TreeCloner {
+
+ private static final Logger LOG = LoggingManager.getLoggerForClass();
+
+ /**
+ * Number of Threads to configure when running a Thread Group during a
validation
+ */
+ protected static final int VALIDATION_NUMBER_OF_THREADS =
JMeterUtils.getPropDefault("testplan_validation.nb_threads_per_thread_group",
1); //$NON-NLS-1$
+ /**
+ * Ignore or not timers during a Thread Group validation
+ */
+ protected static final boolean VALIDATION_IGNORE_TIMERS =
JMeterUtils.getPropDefault("testplan_validation.ignore_timers", true);
//$NON-NLS-1$
+
+ /**
+ * Number of iterations to run during a Thread Group validation
+ */
+ protected static final int VALIDATION_ITERATIONS =
JMeterUtils.getPropDefault("testplan_validation.number_iterations", 1);
//$NON-NLS-1$
+
+ static {
+ if(LOG.isInfoEnabled()) {
+ LOG.info("Running validation with number of
threads:"+VALIDATION_NUMBER_OF_THREADS
+ + ", ignoreTimers:"+VALIDATION_IGNORE_TIMERS
+ + ", number of iterations:"+VALIDATION_ITERATIONS);
+ }
+ }
+
+ public TreeClonerForValidation() {
+ this(false);
+ }
+
+ public TreeClonerForValidation(boolean honourNoThreadClone) {
+ super(honourNoThreadClone);
+ }
+
+ /**
+ * @see org.apache.jmeter.engine.TreeCloner#addNodeToTree(java.lang.Object)
+ */
+ @Override
+ protected Object addNodeToTree(Object node) {
+ if(VALIDATION_IGNORE_TIMERS && node instanceof Timer) {
+ return node; // don't add the timer
+ } else {
+ Object clonedNode = super.addNodeToTree(node);
+ if(clonedNode instanceof org.apache.jmeter.threads.ThreadGroup) {
+
((ThreadGroup)clonedNode).setNumThreads(VALIDATION_NUMBER_OF_THREADS);
+ if(((AbstractThreadGroup)clonedNode).getSamplerController()
instanceof LoopController) {
+
((LoopController)((AbstractThreadGroup)clonedNode).getSamplerController()).setLoops(VALIDATION_ITERATIONS);
+ }
+ }
+ return clonedNode;
+ }
+ }
+}
Propchange:
jmeter/trunk/src/core/org/apache/jmeter/gui/action/validation/TreeClonerForValidation.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1736508&r1=1736507&r2=1736508&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
(original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Thu
Mar 24 21:14:46 2016
@@ -1216,6 +1216,7 @@ user_parameters_title=User Parameters
userdn=Username
username=Username
userpw=Password
+validate_threadgroup=Validate
value=Value
value_to_quote_meta=Value to escape from ORO Regexp meta chars
var_name=Reference Name
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=1736508&r1=1736507&r2=1736508&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
Thu Mar 24 21:14:46 2016
@@ -1201,6 +1201,7 @@ user_parameters_title=Param\u00E8tres Ut
userdn=Identifiant
username=Nom d'utilisateur \:
userpw=Mot de passe
+validate_threadgroup=Valider
value=Valeur \:
value_to_quote_meta=Valeur \u00E0 \u00E9chapper des caract\u00E8res
sp\u00E9ciaux utilis\u00E8s par ORO Regexp
var_name=Nom de r\u00E9f\u00E9rence \:
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=1736508&r1=1736507&r2=1736508&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
Thu Mar 24 21:14:46 2016
@@ -94,6 +94,12 @@ public abstract class AbstractThreadGrou
runTgNotimers.addActionListener(ActionRouter.getInstance());
runTgNotimers.setActionCommand(ActionNames.RUN_TG_NO_TIMERS);
pop.add(runTgNotimers);
+
+ JMenuItem validateTg = new
JMenuItem(JMeterUtils.getResString("validate_threadgroup"));
+ validateTg.setName("validate_threadgroup");
+ validateTg.addActionListener(ActionRouter.getInstance());
+ validateTg.setActionCommand(ActionNames.VALIDATE_TG);
+ pop.add(validateTg);
}
MenuFactory.addEditMenu(pop, true);
Modified: jmeter/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1736508&r1=1736507&r2=1736508&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml (original)
+++ jmeter/trunk/xdocs/changes.xml Thu Mar 24 21:14:46 2016
@@ -279,6 +279,7 @@ Summary
<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>
<li><bug>59207</bug>Change the font color of errorsOrFatalsLabel to red when
an error occurs. Contributed by Antonio Gomes Rodrigues (ra0077 at
gmail.com)</li>
+<li><bug>58941</bug>Create a new Starter that runs thread groups in validation
mode (1 thread only, 1 iteration, no pause all customizable)</li>
</ul>
<ch_section>Non-functional changes</ch_section>
<ul>