sebb 2005/05/28 03:17:31
Modified: xdocs changes.xml
src/core/org/apache/jmeter/engine/util ValueReplacer.java
ReplaceFunctionsWithStrings.java
xdocs/images/screenshots proxy_control.png
src/protocol/http/org/apache/jmeter/protocol/http/proxy
ProxyControl.java
src/protocol/http/org/apache/jmeter/protocol/http/proxy/gui
ProxyControlGui.java
xdocs/usermanual component_reference.xml
src/core/org/apache/jmeter/resources messages.properties
Log:
Bug 35026 - add RE pattern matching to Proxy; prevent replacement of
TestElement.gui_class etc
Revision Changes Path
1.25 +3 -1 jakarta-jmeter/xdocs/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/jakarta-jmeter/xdocs/changes.xml,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- changes.xml 28 May 2005 08:58:46 -0000 1.24
+++ changes.xml 28 May 2005 10:17:31 -0000 1.25
@@ -41,6 +41,7 @@
<li>Allow JavaScript variable name to be omitted</li>
<li>Changed following Samplers to set sample label from sampler name</li>
<li>All Test elements can be saved as a graphics image to a file</li>
+<li>Bug 35026 - add RE pattern matching to Proxy</li>
</ul>
<h4>Bug fixes:</h4>
<ul>
@@ -55,6 +56,7 @@
<li>Fix various samplers to avoid NPEs when incomplete data is provided</li>
<li>Fix Cookie Manager to use seconds; add debug</li>
<li>Bug 35067 - set up filename when using -t option</li>
+<li>Don't substitute TestElement.* properties by UDVs in Proxy</li>
</ul>
<h3>Version 2.0.3</h3>
1.16 +21 -8
jakarta-jmeter/src/core/org/apache/jmeter/engine/util/ValueReplacer.java
Index: ValueReplacer.java
===================================================================
RCS file:
/home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/engine/util/ValueReplacer.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ValueReplacer.java 29 Apr 2005 00:21:23 -0000 1.15
+++ ValueReplacer.java 28 May 2005 10:17:31 -0000 1.16
@@ -95,6 +95,15 @@
setProperties(el, newProps);
}
+ public void reverseReplace(TestElement el, boolean regexMatch) throws
InvalidVariableException
+ {
+ Collection newProps =
+ replaceValues(
+ el.propertyIterator(),
+ new ReplaceFunctionsWithStrings(masterFunction, variables,
regexMatch));
+ setProperties(el, newProps);
+ }
+
public void undoReverseReplace(TestElement el)
throws InvalidVariableException
{
@@ -131,15 +140,19 @@
JMeterProperty val = iter.next();
if (log.isDebugEnabled())
{
- log.debug("About to replace in property of tipe: "
+ log.debug("About to replace in property of type: "
+val.getClass()+": "+val);
}
if (val instanceof StringProperty)
{
- val = transform.transformValue(val);
- if (log.isDebugEnabled())
- {
- log.debug("Replacement result: " +val);
+ // Must not convert TestElement.gui_class etc
+ // TODO but perhaps we want to convert TestElement.name ?
+ if (!val.getName().startsWith("TestElement.")) {
+ val = transform.transformValue(val);
+ if (log.isDebugEnabled())
+ {
+ log.debug("Replacement result: " +val);
+ }
}
}
else if (val instanceof MultiProperty)
@@ -161,7 +174,7 @@
else {
if (log.isDebugEnabled())
{
- log.debug("Won't replace.");
+ log.debug("Won't replace "+val);
}
}
props.add(val);
1.4 +50 -8
jakarta-jmeter/src/core/org/apache/jmeter/engine/util/ReplaceFunctionsWithStrings.java
Index: ReplaceFunctionsWithStrings.java
===================================================================
RCS file:
/home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/engine/util/ReplaceFunctionsWithStrings.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ReplaceFunctionsWithStrings.java 14 Feb 2004 03:34:28 -0000 1.3
+++ ReplaceFunctionsWithStrings.java 28 May 2005 10:17:31 -0000 1.4
@@ -1,6 +1,6 @@
// $Header$
/*
- * Copyright 2003-2004 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,35 +28,77 @@
import org.apache.jmeter.testelement.property.JMeterProperty;
import org.apache.jmeter.testelement.property.StringProperty;
import org.apache.jmeter.util.StringUtilities;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+import org.apache.oro.text.regex.MalformedPatternException;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.PatternCompiler;
+import org.apache.oro.text.regex.PatternMatcher;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
+import org.apache.oro.text.regex.StringSubstitution;
+import org.apache.oro.text.regex.Util;
/**
- * @author ano ano
+ * Transforms strings into variable references
+ * (in spite of the name, which suggests the opposite!)
+ *
* @version $Revision$
*/
public class ReplaceFunctionsWithStrings extends AbstractTransformer
{
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ private boolean regexMatch;// Should we match using regexes?
+
public ReplaceFunctionsWithStrings(
CompoundVariable masterFunction,
Map variables)
{
- super();
- setMasterFunction(masterFunction);
- setVariables(variables);
+ this(masterFunction,variables,false);
}
+ public ReplaceFunctionsWithStrings(
+ CompoundVariable masterFunction,
+ Map variables,
+ boolean regexMatch)
+ {
+ super();
+ setMasterFunction(masterFunction);
+ setVariables(variables);
+ this.regexMatch=regexMatch;
+ }
+
/* (non-Javadoc)
* @see ValueTransformer#transformValue(JMeterProperty)
*/
public JMeterProperty transformValue(JMeterProperty prop)
throws InvalidVariableException
{
+ PatternMatcher pm = new Perl5Matcher();
+ Pattern pattern = null;
+ PatternCompiler compiler = new Perl5Compiler();
Iterator iter = getVariables().keySet().iterator();
String input = prop.getStringValue();
while (iter.hasNext())
{
String key = (String) iter.next();
String value = (String) getVariables().get(key);
- input = StringUtilities.substitute(input, value, "${" + key +
"}");
+ if (regexMatch) {
+ try {
+ pattern = compiler.compile(value);
+ input=Util.substitute(
+ pm,
+ pattern,
+ new StringSubstitution("${"+key+"}"),
+ input,
+ Util.SUBSTITUTE_ALL);
+ } catch (MalformedPatternException e) {
+ log.warn("Malformed pattern "+value);
+ }
+ } else {
+ input = StringUtilities.substitute(input, value, "${" + key
+ "}");
+ }
}
StringProperty newProp = new StringProperty(prop.getName(), input);
return newProp;
1.2 +22 -5 jakarta-jmeter/xdocs/images/screenshots/proxy_control.png
<<Binary file>>
1.57 +39 -5
jakarta-jmeter/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java
Index: ProxyControl.java
===================================================================
RCS file:
/home/cvs/jakarta-jmeter/src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- ProxyControl.java 17 May 2005 22:48:26 -0000 1.56
+++ ProxyControl.java 28 May 2005 10:17:31 -0000 1.57
@@ -88,6 +88,7 @@
public static final String ADD_ASSERTIONS =
"ProxyControlGui.add_assertion";
public static final String GROUPING_MODE =
"ProxyControlGui.grouping_mode";
public static final String USE_KEEPALIVE =
"ProxyControlGui.use_keepalive";
+ public static final String REGEX_MATCH = "ProxyControlGui.regex_match";
public static final int GROUPING_NO_GROUPS = 0;
public static final int GROUPING_ADD_SEPARATORS = 1;
@@ -100,6 +101,7 @@
private boolean addAssertions;
private int groupingMode;
private boolean useKeepAlive;
+ private boolean regexMatch=false;// Should we match using regexes?
/**
* Tree node where the samples should be stored.
@@ -162,16 +164,38 @@
setProperty(new CollectionProperty(EXCLUDE_LIST, new HashSet(list)));
}
+ /**
+ * @param b
+ */
+ public void setRegexMatch(boolean b)
+ {
+ regexMatch=b;
+ setProperty(new BooleanProperty(REGEX_MATCH,b));
+ }
+
public String getClassLabel()
{
return JMeterUtils.getResString("proxy_title");
}
+ public boolean getAssertions() {
+ return getPropertyAsBoolean(ADD_ASSERTIONS);
+ }
+
+ public int getGroupingMode() {
+ return getPropertyAsInt(GROUPING_MODE);
+ }
+
public int getPort()
{
return getPropertyAsInt(PORT);
}
+ public String getPortString()
+ {
+ return getPropertyAsString(PORT);
+ }
+
public int getDefaultPort()
{
return DEFAULT_PORT;
@@ -182,6 +206,16 @@
return getPropertyAsBoolean(CAPTURE_HTTP_HEADERS);
}
+ public boolean getUseKeepalive()
+ {
+ return getPropertyAsBoolean(USE_KEEPALIVE,true);
+ }
+
+ public boolean getRegexMatch()
+ {
+ return getPropertyAsBoolean(REGEX_MATCH,false);
+ }
+
public Class getGuiClass()
{
return
org.apache.jmeter.protocol.http.proxy.gui.ProxyControlGui.class;
@@ -267,7 +301,7 @@
replaceValues(sampler, subConfigs, userDefinedVariables);
sampler.setUseKeepAlive(useKeepAlive);
sampler.setProperty(
- TestElement.GUI_CLASS,
+ TestElement.GUI_CLASS, //TODO - allow for HttpClient sampler
...
"org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui");
placeSampler(sampler, subConfigs, myTarget);
@@ -746,12 +780,12 @@
try
{
- replacer.reverseReplace(sampler);
+ replacer.reverseReplace(sampler,regexMatch);
for (int i = 0; i < configs.length; i++)
{
if (configs[i] != null)
{
- replacer.reverseReplace(configs[i]);
+ replacer.reverseReplace(configs[i],regexMatch);
}
}
1.44 +24 -11
jakarta-jmeter/src/protocol/http/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java
Index: ProxyControlGui.java
===================================================================
RCS file:
/home/cvs/jakarta-jmeter/src/protocol/http/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- ProxyControlGui.java 17 May 2005 22:58:38 -0000 1.43
+++ ProxyControlGui.java 28 May 2005 10:17:31 -0000 1.44
@@ -103,6 +103,11 @@
*/
private JCheckBox useKeepAlive;
+ /*
+ * Use regexes to match the source data
+ */
+ private JCheckBox regexMatch;
+
/**
* List of available target controllers
*/
@@ -169,6 +174,7 @@
model.setGroupingMode(groupingMode.getSelectedIndex());
model.setAssertions(addAssertions.isSelected());
model.setUseKeepAlive(useKeepAlive.isSelected());
+ model.setRegexMatch(regexMatch.isSelected());
TreeNodeWrapper nw=
(TreeNodeWrapper)targetNodes.getSelectedItem();
if (nw == null)
{
@@ -219,13 +225,14 @@
log.debug("Configuring gui with " + element);
super.configure(element);
model = (ProxyControl)element;
- portField.setText(model.getPropertyAsString(ProxyControl.PORT));
-
httpHeaders.setSelected(model.getPropertyAsBoolean(ProxyControl.CAPTURE_HTTP_HEADERS));
-
groupingMode.setSelectedIndex(model.getPropertyAsInt(ProxyControl.GROUPING_MODE));
-
addAssertions.setSelected(model.getPropertyAsBoolean(ProxyControl.ADD_ASSERTIONS));
-
useKeepAlive.setSelected(model.getPropertyAsBoolean(ProxyControl.USE_KEEPALIVE,true));
+ portField.setText(model.getPortString());
+ httpHeaders.setSelected(model.getCaptureHttpHeaders());
+ groupingMode.setSelectedIndex(model.getGroupingMode());
+ addAssertions.setSelected(model.getAssertions());
+ useKeepAlive.setSelected(model.getUseKeepalive());
+ regexMatch.setSelected(model.getRegexMatch());
- reinitializeTargetCombo();
+ reinitializeTargetCombo();//TODO is this needed? What does it do?
populateTable(includeModel, model.getIncludePatterns().iterator());
populateTable(excludeModel, model.getExcludePatterns().iterator());
@@ -284,6 +291,7 @@
|| command.equals(ProxyControl.ADD_ASSERTIONS)
|| command.equals(ProxyControl.GROUPING_MODE)
|| command.equals(ProxyControl.USE_KEEPALIVE)
+ || command.equals(ProxyControl.REGEX_MATCH)
)
{
enableRestart();
@@ -485,6 +493,12 @@
useKeepAlive.addActionListener(this);
useKeepAlive.setActionCommand(ProxyControl.USE_KEEPALIVE);
+ regexMatch = new JCheckBox(JMeterUtils.getResString("proxy_regex"));
+ regexMatch.setName(ProxyControl.REGEX_MATCH);
+ regexMatch.setSelected(false);
+ regexMatch.addActionListener(this);
+ regexMatch.setActionCommand(ProxyControl.REGEX_MATCH);
+
HorizontalPanel panel = new HorizontalPanel();
panel.add(label);
panel.add(portField);
@@ -494,6 +508,7 @@
panel.add(useKeepAlive);
panel.add(addAssertions);
+ panel.add(regexMatch);
return panel;
}
@@ -720,9 +735,7 @@
name.append(seperator);
buildNodesModel(cur, name.toString(), 0);
}
- else {
- log.error("Cannot process "+te);
- }
+ // Ignore everything else
}
}
}
1.112 +22 -3 jakarta-jmeter/xdocs/usermanual/component_reference.xml
Index: component_reference.xml
===================================================================
RCS file: /home/cvs/jakarta-jmeter/xdocs/usermanual/component_reference.xml,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -r1.111 -r1.112
--- component_reference.xml 28 May 2005 08:58:18 -0000 1.111
+++ component_reference.xml 28 May 2005 10:17:31 -0000 1.112
@@ -1509,6 +1509,10 @@
<properties>
<property name="Name" required="No">Descriptive name for this
controller that is shown in the tree.</property>
<property name="Port" required="Yes">The port that the Proxy Server
listens to. 8080 is the default, but you can change it.</property>
+ <property name="Capture HTTP Headers" required="Yes">Should
headers be added to the plan?</property>
+ <property name="Set Keep-Alive" required="Yes">Automatically
set Keep-Alive in the generated samplers?</property>
+ <property name="Add Assertions" required="Yes">Add a blank
assertion to each sampler?</property>
+ <property name="Regex Matching" required="Yes">Use Regex
Matching when replacing variables?</property>
<!--TODO: there's some undocumented flags here -->
<property name="Target Controller" required="Yes">The controller
where the proxy will store the generated samples. By default, it will look for
a Recording Controller and store them there wherever it is.</property>
<property name="Grouping" required="Yes">Whether to group samplers
for requests from a single "click" (requests received without significant time
separation), and how to represent that grouping in the recording:
@@ -1527,7 +1531,6 @@
recorded</b>.</property>
<property name="Patterns to Exclude" required="No">Regular
expressions that are matched against the URL that is sampled.
<b>Any requests that match one or more Exclude pattern are
<i>not</i> recorded</b>.</property>
- <property name="Clear Buttons" required="N/A">Remove all regular
expressions from the list.</property>
<property name="Start Button" required="N/A">Start the proxy server.
JMeter writes the following message to the console once the proxy server has
started up and is ready to take requests: "Proxy up and running!".</property>
<property name="Stop Button" required="N/A">Stop the proxy
server.</property>
<property name="Restart Button" required="N/A">Stops and restarts
the proxy server. This is
@@ -1574,12 +1577,28 @@
those in the other HTTP Request Defaults. See <a
href="best-practices.html#proxy_server"> Best
Practices with the Proxy Server</a> for more info.</p>
-<p>Similarly, if the HTTP Proxy Server finds <complink name="User Defined
Variables"/> directly within the
+<p>Similarly, if the HTTP Proxy Server finds <complink name="User Defined
Variables"/> (UDV) directly within the
controller where samples are being stored, or directly within any of its
parent controllers, the recorded samples
will have any occurences of the values of those variables replaced by the
corresponding variable. Again, you can
place User Defined Variables directly within the HTTP Proxy Server to
override the values to be replaced. See
<a href="best-practices.html#proxy_server"> Best Practices with the Proxy
Server</a> for more info.</p>
+<p>Replacement by Variables: by default, the Proxy server looks for all
occurences of UDV values.
+If you define the variable "WEB" with the value "www", for example,
+the string "www" will be replaced by ${WEB} wherever it is found.
+To avoid this happening everywhere, set the "Regex Matching" check-box.
+This tells the proxy server to treat values as Regexes (using ORO).
+<br></br>
+If you want to match a whole string only, enclose it in ^$, e.g. "^thus$".
+<br></br>
+If you want to match /images at the start of a string only, use the value
"^/images".
+Jakarta ORO also supports zero-width look-ahead, so one can match
/images/...
+but retain the trailing / in the output by using "^/images(?=/)".
+Note that the current version of Jakara ORO does not support look-behind -
i.e. "(?<=...)".
+<br></br>
+If there are any problems interpreting any variables as patterns, these are
reported in jmeter.log,
+so be sure to check this if UDVs are not working as expected.
+</p>
<p>When you are done recording your test samples, stop the proxy server (hit
the "stop" button). Remember to reset
your browser's proxy settings. Now, you may want to sort and re-order the
test script, add timers, listeners, a
cookie manager, etc.</p>
1.146 +1 -0
jakarta-jmeter/src/core/org/apache/jmeter/resources/messages.properties
Index: messages.properties
===================================================================
RCS file:
/home/cvs/jakarta-jmeter/src/core/org/apache/jmeter/resources/messages.properties,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -r1.145 -r1.146
--- messages.properties 25 May 2005 22:09:17 -0000 1.145
+++ messages.properties 28 May 2005 10:17:31 -0000 1.146
@@ -439,6 +439,7 @@
proxy_assertions=Add Assertions
proxy_cl_error=If specifying a proxy server, host and port must be given
proxy_headers=Capture HTTP Headers
+proxy_regex=Regex matching
proxy_separators=Add Separators
proxy_target=Target Controller\:
proxy_title=HTTP Proxy Server
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]