Author: sebb
Date: Mon Mar 31 07:05:02 2008
New Revision: 642994
URL: http://svn.apache.org/viewvc?rev=642994&view=rev
Log:
Regex Function can now also be applied to a variable rather than just the
previous sample result.
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
jakarta/jmeter/trunk/src/functions/org/apache/jmeter/functions/RegexFunction.java
jakarta/jmeter/trunk/test/src/org/apache/jmeter/functions/TestRegexFunction.java
jakarta/jmeter/trunk/xdocs/changes.xml
jakarta/jmeter/trunk/xdocs/usermanual/functions.xml
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=642994&r1=642993&r2=642994&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
(original)
+++
jakarta/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
Mon Mar 31 07:05:02 2008
@@ -572,6 +572,7 @@
regexfunc_param_3=Which match to use. An integer 1 or greater, RAND to
indicate JMeter should randomly choose, A float, or ALL indicating all matches
should be used ([1])
regexfunc_param_4=Between text. If ALL is selected, the between text will be
used to generate the results ([""])
regexfunc_param_5=Default text. Used instead of the template if the regular
expression finds no matches ([""])
+regexfunc_param_7=Input variable name containing the text to be parsed
([previous sample])
remote_error_init=Error initialising remote server
remote_error_starting=Error starting remote server
remote_exit=Remote Exit
Modified:
jakarta/jmeter/trunk/src/functions/org/apache/jmeter/functions/RegexFunction.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/functions/org/apache/jmeter/functions/RegexFunction.java?rev=642994&r1=642993&r2=642994&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/functions/org/apache/jmeter/functions/RegexFunction.java
(original)
+++
jakarta/jmeter/trunk/src/functions/org/apache/jmeter/functions/RegexFunction.java
Mon Mar 31 07:05:02 2008
@@ -41,6 +41,11 @@
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Util;
+/**
+ * Implements regular expression parsing of sample results and variables
+ */
+
+// @see TestRegexFunction for unit tests
public class RegexFunction extends AbstractFunction implements Serializable {
private static final Logger log = LoggingManager.getLoggerForClass();
@@ -64,14 +69,15 @@
// Number of parameters expected - used to reject invalid calls
private static final int MIN_PARAMETER_COUNT = 2;
- private static final int MAX_PARAMETER_COUNT = 6;
+ private static final int MAX_PARAMETER_COUNT = 7;
static {
desc.add(JMeterUtils.getResString("regexfunc_param_1"));//
regex //$NON-NLS-1$
desc.add(JMeterUtils.getResString("regexfunc_param_2"));//
template //$NON-NLS-1$
desc.add(JMeterUtils.getResString("regexfunc_param_3"));//
which match //$NON-NLS-1$
desc.add(JMeterUtils.getResString("regexfunc_param_4"));//
between text //$NON-NLS-1$
desc.add(JMeterUtils.getResString("regexfunc_param_5"));//
default text //$NON-NLS-1$
- desc.add(JMeterUtils.getResString("function_name_paropt")); //
variable name //$NON-NLS-1$
+ desc.add(JMeterUtils.getResString("function_name_paropt")); //
output variable name //$NON-NLS-1$
+ desc.add(JMeterUtils.getResString("regexfunc_param_7"));// input
variable //$NON-NLS-1$
}
public RegexFunction() {
@@ -94,6 +100,7 @@
throws InvalidVariableException {
String valueIndex = "", defaultValue = "", between = "";
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String name = ""; //$NON-NLS-1$
+ String inputVariable = ""; //$NON-NLS-1$
Pattern searchPattern;
Object[] tmplt;
try {
@@ -104,7 +111,7 @@
if (values.length > 2) {
valueIndex = ((CompoundVariable)
values[2]).execute();
}
- if (valueIndex.equals("")) { //$NON-NLS-1$
+ if (valueIndex.length() == 0) {
valueIndex = "1"; //$NON-NLS-1$
}
@@ -114,30 +121,45 @@
if (values.length > 4) {
String dv = ((CompoundVariable)
values[4]).execute();
- if (!dv.equals("")) { //$NON-NLS-1$
+ if (dv.length() != 0) {
defaultValue = dv;
}
}
if (values.length > 5) {
- name = ((CompoundVariable) values[values.length
- 1]).execute();
+ name = ((CompoundVariable) values[5]).execute();
}
+
+ if (values.length > 6) {
+ inputVariable = ((CompoundVariable) values[6]).execute();
+ }
} catch (MalformedCachePatternException e) {
throw new InvalidVariableException(e.toString());
}
- JMeterVariables vars = getVariables();// Relatively expensive
-
// operation, so do it once
- vars.put(name, defaultValue);
- if (previousResult == null ||
previousResult.getResponseData().length == 0) {
+ // Relatively expensive operation, so do it once
+ JMeterVariables vars = getVariables();
+
+ if (name.length() > 0) {
+ vars.put(name, defaultValue);
+ }
+
+ String textToMatch=null;
+
+ if (inputVariable.length() > 0){
+ textToMatch=vars.get(inputVariable);
+ } else if (previousResult != null){
+ textToMatch = previousResult.getResponseDataAsString();
+ }
+
+ if (textToMatch == null || textToMatch.length() == 0) {
return defaultValue;
}
List collectAllMatches = new ArrayList();
try {
PatternMatcher matcher = JMeterUtils.getMatcher();
- String responseText =
previousResult.getResponseDataAsString();
- PatternMatcherInput input = new
PatternMatcherInput(responseText);
+ PatternMatcherInput input = new
PatternMatcherInput(textToMatch);
while (matcher.contains(input, searchPattern)) {
MatchResult match = matcher.getMatch();
collectAllMatches.add(match);
@@ -146,7 +168,9 @@
log.error("", e); //$NON-NLS-1$
return defaultValue;
} finally {
- vars.put(name + "_matchNr", "" +
collectAllMatches.size()); //$NON-NLS-1$ //$NON-NLS-2$
+ if (name.length() > 0){
+ vars.put(name + "_matchNr", "" +
collectAllMatches.size()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
if (collectAllMatches.size() == 0) {
@@ -208,7 +232,9 @@
result.append(match.group(((Integer)
template[a]).intValue()));
}
}
- vars.put(namep, result.toString());
+ if (namep.length() > 0){
+ vars.put(namep, result.toString());
+ }
return result.toString();
}
Modified:
jakarta/jmeter/trunk/test/src/org/apache/jmeter/functions/TestRegexFunction.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jmeter/functions/TestRegexFunction.java?rev=642994&r1=642993&r2=642994&view=diff
==============================================================================
---
jakarta/jmeter/trunk/test/src/org/apache/jmeter/functions/TestRegexFunction.java
(original)
+++
jakarta/jmeter/trunk/test/src/org/apache/jmeter/functions/TestRegexFunction.java
Mon Mar 31 07:05:02 2008
@@ -29,7 +29,9 @@
import org.apache.jmeter.threads.JMeterVariables;
public class TestRegexFunction extends JMeterTestCase {
- RegexFunction variable;
+ private static final String INPUT_VARIABLE_NAME = "INVAR";
+
+ RegexFunction variable;
SampleResult result;
@@ -56,6 +58,8 @@
+ "</row></company-xmlext-query-ret>";
result.setResponseData(data.getBytes());
vars = new JMeterVariables();
+ String data2 = "The quick brown fox jumped over the
lazy dog 123 times";
+ vars.put(INPUT_VARIABLE_NAME, data2);
jmctx.setVariables(vars);
jmctx.setPreviousResult(result);
}
@@ -69,6 +73,59 @@
String match = variable.execute(result, null);
assertEquals("5", match);
}
+
+ // Test with output variable name
+ public void testVariableExtraction1a() throws Exception {
+ params = new LinkedList();
+ params.add(new CompoundVariable("<value
field=\"(pinposition\\d+)\">(\\d+)</value>"));
+ params.add(new CompoundVariable("$2$")); // template
+ params.add(new CompoundVariable("2")); // match number
+ params.add(new CompoundVariable("-")); // ALL separator
+ params.add(new CompoundVariable("default"));
+ params.add(new CompoundVariable("OUTVAR"));
+ variable.setParameters(params);
+ String match = variable.execute(result, null);
+ assertEquals("3", vars.getObject("OUTVAR_matchNr"));
+ assertEquals("5", match);
+ assertEquals("5", vars.getObject("OUTVAR"));
+ assertEquals("<value field=\"pinposition2\">5</value>",
vars.getObject("OUTVAR_g0"));
+ assertEquals("pinposition2", vars.getObject("OUTVAR_g1"));
+ assertEquals("5", vars.getObject("OUTVAR_g2"));
+ }
+
+ // Test with empty output variable name
+ public void testVariableExtraction1b() throws Exception {
+ params = new LinkedList();
+ params.add(new CompoundVariable("<value
field=\"(pinposition\\d+)\">(\\d+)</value>"));
+ params.add(new CompoundVariable("$2$")); // template
+ params.add(new CompoundVariable("2")); // match number
+ params.add(new CompoundVariable("-")); // ALL separator
+ params.add(new CompoundVariable("default"));
+ params.add(new CompoundVariable(""));
+ variable.setParameters(params);
+ String match = variable.execute(result, null);
+ assertEquals("5", match);
+ assertNull(vars.getObject("OUTVAR"));
+ }
+
+ public void testVariableExtractionFromVariable() throws Exception {
+ params = new LinkedList();
+ params.add(new CompoundVariable("(\\d+)\\s+(\\w+)"));
+ params.add(new CompoundVariable("$2$")); // template
+ params.add(new CompoundVariable("1")); // match number
+ params.add(new CompoundVariable("-")); // ALL separator
+ params.add(new CompoundVariable("default"));
+ params.add(new CompoundVariable("OUTVAR"));
+ params.add(new CompoundVariable(INPUT_VARIABLE_NAME));
+ variable.setParameters(params);
+ String match = variable.execute(result, null);
+ assertEquals("1", vars.getObject("OUTVAR_matchNr"));
+ assertEquals("times", match);
+ assertEquals("times", vars.getObject("OUTVAR"));
+ assertEquals("123 times", vars.getObject("OUTVAR_g0"));
+ assertEquals("123", vars.getObject("OUTVAR_g1"));
+ assertEquals("times", vars.getObject("OUTVAR_g2"));
+ }
public void testVariableExtraction2() throws Exception {
params = new LinkedList();
Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=642994&r1=642993&r2=642994&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Mar 31 07:05:02 2008
@@ -132,6 +132,7 @@
<li>FTP Sampler sets latency = time to login</li>
<li>FTP Sampler sets a URL if it can</li>
<li>Bug 41921 - add option for samplers to store MD5 of response; done for
HTTP Samplers.</li>
+<li>Regex Function can now also be applied to a variable rather than just the
previous sample result.</li>
</ul>
<h4>Non-functional changes</h4>
Modified: jakarta/jmeter/trunk/xdocs/usermanual/functions.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/functions.xml?rev=642994&r1=642993&r2=642994&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/functions.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/functions.xml Mon Mar 31 07:05:02 2008
@@ -66,38 +66,43 @@
${VARIABLE}
</pre>
</p>
+<p>
+If an undefined function or variable is referenced, JMeter does not report/log
an error - the reference is returned unchanged.
+For example if UNDEF is not defined as a variable, then the value of ${UNDEF}
is ${UNDEF}.
+</p>
<note>
Properties are not the same as variables.
-Variables are local to a thread; properties are common to all threads.
+Variables are local to a thread; properties are common to all threads,
+and need to be referenced using the __P or __property function.
</note>
-<p>List of functions:</p>
+<p>List of functions, loosely grouped into types.</p>
<table border="1">
- <tr><th>Name</th><th>Comment</th></tr>
+ <tr><th>Type of function</th><th>Name</th><th>Comment</th></tr>
<!-- N.B. the leading space is needed to ensure the content is
processed -->
- <tr><td> <a href="#__regexFunction">regexFunction</a></td><td>parse
previous response using a regular expression</td></tr>
- <tr><td> <a href="#__counter">counter</a></td><td>generate an
incrementing number</td></tr>
- <tr><td> <a href="#__threadNum">threadNum</a></td><td>get thread
number</td></tr>
- <tr><td> <a href="#__intSum">intSum</a></td><td>add int
numbers</td></tr>
- <tr><td> <a href="#__longSum">longSum</a></td><td>add long
numbers</td></tr>
- <tr><td> <a href="#__StringFromFile">StringFromFile</a></td><td>read a
line from a file</td></tr>
- <tr><td> <a href="#__machineName">machineName</a></td><td>get the
local machine name</td></tr>
- <tr><td> <a href="#__javaScript">javaScript</a></td><td>process
JavaScript (Mozilla Rhino)</td></tr>
- <tr><td> <a href="#__Random">Random</a></td><td>generate a random
number</td></tr>
- <tr><td> <a href="#__CSVRead">CSVRead</a></td><td>read from CSV
delimited file</td></tr>
- <tr><td> <a href="#__property">property</a> </td><td>read a
property</td></tr>
- <tr><td> <a href="#__P">P</a></td><td>read a property (shorthand
method)</td></tr>
- <tr><td> <a href="#__setProperty">setProperty</a></td><td>set a JMeter
property</td></tr>
- <tr><td> <a href="#__log">log</a></td><td>log (or display) a message
(and return the value)</td></tr>
- <tr><td> <a href="#__logn">logn</a></td><td>log (or display) a message
(empty return value)</td></tr>
- <tr><td> <a href="#__BeanShell">BeanShell</a></td><td>run a BeanShell
script</td></tr>
- <tr><td> <a href="#__split">split</a></td><td>Split a string into
variables</td></tr>
- <tr><td> <a href="#__XPath">XPath</a></td><td>Use an XPath expression
to read from a file</td></tr>
- <tr><td> <a href="#__time">time</a></td><td>return current time in
various formats</td></tr>
- <tr><td> <a href="#__jexl">jexl</a></td><td>evaluate a Commons Jexl
expression</td></tr>
- <tr><td> <a href="#__V">V</a></td><td>evaluate a variable
name</td></tr>
- <tr><td> <a href="#__eval">eval</a></td><td>evaluate a variable
expression</td></tr>
- <tr><td> <a href="#__evalVar">evalVar</a></td><td>evaluate an
expression stored in a variable</td></tr>
+ <tr><td>Information</td><td> <a
href="#__threadNum">threadNum</a></td><td>get thread number</td></tr>
+ <tr><td>Information</td><td> <a
href="#__machineName">machineName</a></td><td>get the local machine
name</td></tr>
+ <tr><td>Information</td><td> <a href="#__time">time</a></td><td>return
current time in various formats</td></tr>
+ <tr><td>Information</td><td> <a href="#__log">log</a></td><td>log (or
display) a message (and return the value)</td></tr>
+ <tr><td>Information</td><td> <a href="#__logn">logn</a></td><td>log
(or display) a message (empty return value)</td></tr>
+ <tr><td>Input</td><td> <a
href="#__StringFromFile">StringFromFile</a></td><td>read a line from a
file</td></tr>
+ <tr><td>Input</td><td> <a href="#__CSVRead">CSVRead</a></td><td>read
from CSV delimited file</td></tr>
+ <tr><td>Input</td><td> <a href="#__XPath">XPath</a></td><td>Use an
XPath expression to read from a file</td></tr>
+ <tr><td>Calculation</td><td> <a
href="#__counter">counter</a></td><td>generate an incrementing number</td></tr>
+ <tr><td>Calculation</td><td> <a
href="#__intSum">intSum</a></td><td>add int numbers</td></tr>
+ <tr><td>Calculation</td><td> <a
href="#__longSum">longSum</a></td><td>add long numbers</td></tr>
+ <tr><td>Calculation</td><td> <a
href="#__Random">Random</a></td><td>generate a random number</td></tr>
+ <tr><td>Calculation</td><td> <a
href="#__regexFunction">regexFunction</a></td><td>parse previous response using
a regular expression</td></tr>
+ <tr><td>Scripting</td><td> <a
href="#__BeanShell">BeanShell</a></td><td>run a BeanShell script</td></tr>
+ <tr><td>Scripting</td><td> <a
href="#__javaScript">javaScript</a></td><td>process JavaScript (Mozilla
Rhino)</td></tr>
+ <tr><td>Scripting</td><td> <a href="#__jexl">jexl</a></td><td>evaluate
a Commons Jexl expression</td></tr>
+ <tr><td>Properties</td><td> <a href="#__property">property</a>
</td><td>read a property</td></tr>
+ <tr><td>Properties</td><td> <a href="#__P">P</a></td><td>read a
property (shorthand method)</td></tr>
+ <tr><td>Properties</td><td> <a
href="#__setProperty">setProperty</a></td><td>set a JMeter property</td></tr>
+ <tr><td>Variables</td><td> <a href="#__split">split</a></td><td>Split
a string into variables</td></tr>
+ <tr><td>Variables</td><td> <a href="#__V">V</a></td><td>evaluate a
variable name</td></tr>
+ <tr><td>Variables</td><td> <a href="#__eval">eval</a></td><td>evaluate
a variable expression</td></tr>
+ <tr><td>Variables</td><td> <a
href="#__evalVar">evalVar</a></td><td>evaluate an expression stored in a
variable</td></tr>
</table>
<p></p>
<subsection name="§-num;.1 What can functions do" anchor="what_can_do">
@@ -217,10 +222,10 @@
<subsection name="§-num;.5 Functions" anchor="functions">
<component index="§-num;.5.1" name="__regexFunction">
-<description><p>The Regex Function is used to parse the previous response
using any regular
+<description><p>The Regex Function is used to parse the previous response (or
the value of a variable) using any regular
expression (provided by user). The function returns the template string with
variable values filled
in.</p>
-<p>The __regexFunction stores values for future use. In the sixth parameter,
you can specify
+<p>The __regexFunction can also store values for future use. In the sixth
parameter, you can specify
a reference name. After this function executes, the same values can be
retrieved at later times
using the syntax for user-defined values. For instance, if you enter
"refName" as the sixth
parameter you will be able to use:
@@ -259,9 +264,12 @@
<property name="Fourth argument" required="No">If 'ALL' was selected
for the above argument
value, then this argument will be inserted between each appended copy
of the template value.</property>
<property name="Fifth argument" required="No">Default value returned
if no match is found</property>
- <property name="Sixth argument" required="No">A reference name for reusing
the values parsed by this function.<br></br>
+ <property name="Sixth argument" required="No">A reference name for
reusing the values parsed by this function.<br></br>
Stored values are ${refName} (the replacement template string) and
${refName_g#} where "#" is the
group number from the regular expression ("0" can be used to refer to
the entire match).</property>
+ <property name="Seventh argument" required="No">Input variable name.
+ If specified, then the value of the variable is used as the input
instead of using the previous sample result.
+ </property>
</properties>
</component>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]