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="&sect-num;.1 What can functions do" anchor="what_can_do">
@@ -217,10 +222,10 @@
 <subsection name="&sect-num;.5 Functions" anchor="functions">
 
 <component index="&sect-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]

Reply via email to