ASF Bugzilla – Attachment 34139 Details for
Bug 59991
New function __groovy to evaluate Groovy Script
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch implementing this new feature
BUG_59991.patch (text/plain), 11.19 KB, created by
UbikLoadPack support
on 2016-08-11 21:39:41 UTC
(
hide
)
Description:
Patch implementing this new feature
Filename:
MIME Type:
Creator:
UbikLoadPack support
Created:
2016-08-11 21:39:41 UTC
Size:
11.19 KB
patch
obsolete
>Index: bin/jmeter.properties >=================================================================== >--- bin/jmeter.properties (revision 1754678) >+++ bin/jmeter.properties (working copy) >@@ -934,6 +934,16 @@ > # of Test and Thread Listeners. > > #--------------------------------------------------------------------------- >+# Groovy function >+#--------------------------------------------------------------------------- >+ >+#Path to Groovy file containing utility functions to make available to __g function >+#groovy.utilities= >+ >+# Example >+#groovy.utilities=bin/utility.groovy >+ >+#--------------------------------------------------------------------------- > # MailerModel configuration > #--------------------------------------------------------------------------- > >Index: bin/utility.groovy >=================================================================== >--- bin/utility.groovy (revision 0) >+++ bin/utility.groovy (revision 0) >@@ -0,0 +1,2 @@ >+// Uncomment this function and use it with ${__g(factorial(10))} >+// def factorial(n) { n == 1 ? 1 : n * factorial(n - 1) } >\ No newline at end of file >Index: src/core/org/apache/jmeter/resources/messages.properties >=================================================================== >--- src/core/org/apache/jmeter/resources/messages.properties (revision 1755820) >+++ src/core/org/apache/jmeter/resources/messages.properties (working copy) >@@ -382,6 +382,7 @@ > graph_results_no_samples=No of Samples > graph_results_throughput=Throughput > graph_results_title=Graph Results >+groovy_function_expression=Expression to evaluate > grouping_add_separators=Add separators between groups > grouping_in_controllers=Put each group in a new controller > grouping_in_transaction_controllers=Put each group in a new transaction controller >Index: src/core/org/apache/jmeter/resources/messages_fr.properties >=================================================================== >--- src/core/org/apache/jmeter/resources/messages_fr.properties (revision 1755820) >+++ src/core/org/apache/jmeter/resources/messages_fr.properties (working copy) >@@ -375,6 +375,7 @@ > graph_results_no_samples=Nombre d'\u00E9chantillons > graph_results_throughput=D\u00E9bit > graph_results_title=Graphique de r\u00E9sultats >+groovy_function_expression=Expression \u00E0 \u00E9valuer > grouping_add_separators=Ajouter des s\u00E9parateurs entre les groupes > grouping_in_controllers=Mettre chaque groupe dans un nouveau contr\u00F4leur > grouping_in_transaction_controllers=Mettre chaque groupe dans un nouveau contr\u00F4leur de transaction >Index: src/functions/org/apache/jmeter/functions/Groovy.java >=================================================================== >--- src/functions/org/apache/jmeter/functions/Groovy.java (revision 0) >+++ src/functions/org/apache/jmeter/functions/Groovy.java (revision 0) >@@ -0,0 +1,161 @@ >+/** >+ * >+ */ >+package org.apache.jmeter.functions; >+ >+import java.io.BufferedReader; >+import java.io.File; >+import java.io.FileReader; >+import java.util.Collection; >+import java.util.LinkedList; >+import java.util.List; >+import java.util.Properties; >+ >+import javax.script.Bindings; >+import javax.script.ScriptEngine; >+ >+import org.apache.jmeter.engine.util.CompoundVariable; >+import org.apache.jmeter.samplers.SampleResult; >+import org.apache.jmeter.samplers.Sampler; >+import org.apache.jmeter.threads.JMeterContext; >+import org.apache.jmeter.threads.JMeterContextService; >+import org.apache.jmeter.threads.JMeterVariables; >+import org.apache.jmeter.util.JMeterUtils; >+import org.apache.jmeter.util.JSR223TestElement; >+import org.apache.jorphan.logging.LoggingManager; >+import org.apache.log.Logger; >+ >+/** >+ * __g function >+ * Provides a Groovy interpreter >+ * @since 3.1 >+ */ >+public class Groovy extends AbstractFunction { >+ private static final Logger log = LoggingManager.getLoggerForClass(); >+ >+ private static final List<String> desc = new LinkedList<>(); >+ >+ private static final String KEY = "__g"; //$NON-NLS-1$ >+ >+ public static final String INIT_FILE = "groovy.utilities"; //$NON-NLS-1$ >+ >+ static { >+ desc.add(JMeterUtils.getResString("bsh_function_expression"));// $NON-NLS1$ >+ desc.add(JMeterUtils.getResString("function_name_paropt"));// $NON-NLS1$ >+ } >+ >+ private Object[] values; >+ private ScriptEngine scriptEngine; >+ >+ >+ public Groovy() { >+ } >+ >+ /** >+ * Populate variables to be passed to scripts >+ * @param bindings Bindings >+ */ >+ protected void populateBindings(Bindings bindings) { >+ } >+ >+ /** {@inheritDoc} */ >+ @Override >+ public synchronized String execute(SampleResult previousResult, Sampler currentSampler) >+ throws InvalidVariableException { >+ Bindings bindings = scriptEngine.createBindings(); >+ populateBindings(bindings); >+ >+ >+ String script = ((CompoundVariable) values[0]).execute(); >+ String varName = ""; //$NON-NLS-1$ >+ if (values.length > 1) { >+ varName = ((CompoundVariable) values[1]).execute().trim(); >+ } >+ >+ String resultStr = ""; //$NON-NLS-1$ >+ try { >+ >+ // Pass in some variables >+ if (currentSampler != null) { >+ bindings.put("sampler", currentSampler); // $NON-NLS-1$ >+ } >+ >+ if (previousResult != null) { >+ bindings.put("prev", previousResult); //$NON-NLS-1$ >+ } >+ bindings.put("log", log); // $NON-NLS-1$ (this name is fixed) >+ // Add variables for access to context and variables >+ bindings.put("threadName", Thread.currentThread().getName()); >+ JMeterContext jmctx = JMeterContextService.getContext(); >+ bindings.put("ctx", jmctx); // $NON-NLS-1$ (this name is fixed) >+ JMeterVariables vars = jmctx.getVariables(); >+ bindings.put("vars", vars); // $NON-NLS-1$ (this name is fixed) >+ Properties props = JMeterUtils.getJMeterProperties(); >+ bindings.put("props", props); // $NON-NLS-1$ (this name is fixed) >+ // For use in debugging: >+ bindings.put("OUT", System.out); // $NON-NLS-1$ (this name is fixed) >+ >+ >+ // Execute the script >+ Object out = scriptEngine.eval(script, bindings); >+ if (out != null) { >+ resultStr = out.toString(); >+ } >+ >+ if (varName.length() > 0) {// vars will be null on TestPlan >+ if(vars != null) { >+ vars.put(varName, resultStr); >+ } >+ } >+ } catch (Exception ex) // Mainly for bsh.EvalError >+ { >+ log.warn("Error running groovy script", ex); >+ } >+ if(log.isDebugEnabled()) { >+ log.debug("__groovy("+script+","+varName+")=" + resultStr); >+ } >+ return resultStr; >+ >+ } >+ >+ /* >+ * Helper method for use by scripts >+ * >+ */ >+ public void log_info(String s) { >+ log.info(s); >+ } >+ >+ /** {@inheritDoc} */ >+ @Override >+ public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException { >+ checkParameterCount(parameters, 1, 2); >+ values = parameters.toArray(); >+ scriptEngine = JSR223TestElement.getInstance().getEngineByName("groovy"); >+ String fileName = JMeterUtils.getProperty(INIT_FILE); >+ Bindings bindings = scriptEngine.createBindings(); >+ bindings.put("log", log); >+ >+ File file = new File(JMeterUtils.getJMeterHome(), fileName); >+ if(file.exists() && file.canRead()) { >+ try (FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr)) { >+ scriptEngine.eval(reader, bindings); >+ } catch(Exception ex) { >+ log.error("Failed loading script "+ file.getAbsolutePath(), ex); >+ } >+ } >+ } >+ >+ /** {@inheritDoc} */ >+ @Override >+ public String getReferenceKey() { >+ return KEY; >+ } >+ >+ /** {@inheritDoc} */ >+ @Override >+ public List<String> getArgumentDesc() { >+ return desc; >+ } >+ >+} >Index: xdocs/usermanual/functions.xml >=================================================================== >--- xdocs/usermanual/functions.xml (revision 1755638) >+++ xdocs/usermanual/functions.xml (working copy) >@@ -125,6 +125,7 @@ > <tr><td>Calculation</td><td> <a href="#__RandomFromMultipleVars">RandomFromMultipleVars</a></td><td>extracts an element from the values of a set of variables separated by <code>|</code></td><td>3.1</td></tr> > <tr><td>Calculation</td><td> <a href="#__RandomString">RandomString</a></td><td>generate a random string</td><td>2.6</td></tr> > <tr><td>Calculation</td><td> <a href="#__UUID">UUID</a></td><td>generate a random type 4 UUID</td><td>2.9</td></tr> >+ <tr><td>Scripting</td><td> <a href="#__g">g</a></td><td>run a Groovy script</td><td>3.1</td></tr> > <tr><td>Scripting</td><td> <a href="#__BeanShell">BeanShell</a></td><td>run a BeanShell script</td><td>1.X</td></tr> > <tr><td>Scripting</td><td> <a href="#__javaScript">javaScript</a></td><td>process JavaScript (Mozilla Rhino)</td><td>1.9</td></tr> > <tr><td>Scripting</td><td> <a href="#__jexl">jexl</a></td><td>evaluate a Commons Jexl expression. This function is DEPRECATED as of JMeter 3.0, it will be removed in 3.1 version.</td><td>jexl1(1.1)</td></tr> >@@ -909,6 +910,52 @@ > </note> > </component> > >+<component index="§-num;.5.13" name="__g"> >+<description> >+ <p> >+ The g function evaluates <a href="http://groovy-lang.org/" >Apache Groovy</a> scripts passed to it, and returns the result. >+</p> >+<p> >+If the property "<code>groovy.utilities</code>" is defined, it will be loaded by the ScriptEngine. >+This can be used to define common methods and variables. There is a >+sample init file in the bin directory: <code>utility.groovy</code>. >+</p> >+<p> >+The following variables are set before the script is executed: >+<ul> >+<li><code>log</code> - the logger for the BeanShell function (*)</li> >+<li><code>ctx</code> - the current JMeter context variable</li> >+<li><code>vars</code> - the current JMeter variables</li> >+<li><code>props</code> - JMeter Properties object</li> >+<li><code>threadName</code> - the threadName (String)</li> >+<li><code>sampler</code> - the current Sampler, if any</li> >+<li><code>prev</code> - the previous SampleResult, if any</li> >+<li><code>OUT</code> - System.out</li> >+</ul> >+(*) means that this is set before the init file, if any, is processed. >+Other variables vary from invocation to invocation. >+</p> >+</description> >+ >+<properties> >+ <property name="Expression to evaluate" required="Yes">A groovy script (not a file name)</property> >+ <property name="Name of variable" required="No">A reference name for reusing the value >+ computed by this function.</property> >+ >+</properties> >+<p> >+Example: >+<dl> >+<dt><code>${__g(123*456)}</code></dt><dd>returns <code>56088</code></dd> >+<dt><code>${__g("${var}".substring(0\,2))}</code></dt><dd>If var's value is <code>JMeter</code>, it will return <code>JM</code> as it runs <code>String.substring(0,2)</code> </dd> >+</dl> >+</p> >+<note> >+Remember to include any necessary quotes for text strings and JMeter variables that represent text strings. >+</note> >+</component> >+ >+ > <component index="§-num;.5.14" name="__split"> > <description> > <p>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 59991
: 34139 |
34140