Jonathan, I have tried your changes here (only in non-GUI mode) and found no problems. In fact, your changes seem to resolve a problem where I was getting a large number of exceptions such as the following in jmeter.log:
12/28/2002 11:19:41 PM ERROR - jmeter.engine: java.lang.ArrayIndexOutOfBoundsException: 17 at org.apache.oro.text.regex.Perl5Compiler.__emitNode(Perl5Compiler.java:338) at org.apache.oro.text.regex.Perl5Compiler.__parseExpression(Perl5Compiler.java :1375) at org.apache.oro.text.regex.Perl5Compiler.compile(Perl5Compiler.java:1460) at org.apache.oro.text.regex.Perl5Compiler.compile(Perl5Compiler.java:1731) at org.apache.jmeter.assertions.ResponseAssertion.evaluateResponse(ResponseAsse rtion.java:294) at org.apache.jmeter.assertions.ResponseAssertion.getResult(ResponseAssertion.j ava:197) at org.apache.jmeter.threads.JMeterThread.checkAssertions(JMeterThread.java:179 ) at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:144) at java.lang.Thread.run(Thread.java:536) Needless to say, my test script runs much better without these ;-). I will prepare a new patch based on your code and attach it to the existing bugzilla issue. Thanks, Scott -- Scott Eade Backstage Technologies Pty. Ltd. http://www.backstagetech.com.au .Mac Chat/AIM: seade at mac dot com On 27/12/2002 4:03 AM, "Jonathan Carlson" <[EMAIL PROTECTED]> wrote: > Here is a much cleaner (IMHO) fix for the Assertion Results threading problem. > Could someone else try this out and see how it works for them? It works fine > for me in both GUI and non-GUI mode. > > This fix also avoids the problem that Scott found with the previous fix when > running in non-GUI mode. I'm sorry I didn't catch that before you all did, > but I didn't even know that there was a non-GUI mode until recently. > > The below fix assumes a "clean" (without my previous fixes) 1.8 version of > ResponseAssertion.java. > > 1) The compilerMatcher static field replaces the current compiler and matcher > static fields. > 2) The #evaluateResponse method is a replacement for the existing one. > 3) The CompilerMatcher static member class is new. > > One note about this: The benefit of the caching of the compiled patterns here > is not proven, only assumed. Some people, including myself, don't like to add > complexity without demonstrating a need for it. In this case, I really need > to move onto other work that will provide benefit to my company and the added > complexity was quite minimal given the perceived benefit. > > If someone else feels it is important to demonstrate that looking up a cached > compiled pattern truly is cheaper than recompiling the pattern each time, I > would be happy if they would do that. Otherwise, I don't think the added > complexity is enough to warrant it at this point. > > Cheers, Jonathan > > P.S. I'll be on vacation until Friday 2002-01-03. I'll be interested to hear > about other people's success or unsuccess with this patch at that time. (I'm > expecting only success :-) > > > private transient static ThreadLocal compilerMatcher = > new ThreadLocal() > { > protected Object initialValue() > { > return new CompilerMatcher(); > } > }; > > > /** > * Make sure the response satisfies the specified assertion requirements. > * @param response an instance of SampleResult > * @return an instance of AssertionResult > */ > private AssertionResult evaluateResponse(SampleResult response) > { > boolean pass = true; > boolean not = (NOT & getTestType()) > 0; > AssertionResult result = new AssertionResult(); > try > { > String responseString = new String(response.getResponseData()); > // Get the CompilerMatcher for this thread > CompilerMatcher localCompilerMatcher = > (CompilerMatcher) this.compilerMatcher.get(); > Iterator iter = getTestStrings().iterator(); > while (iter.hasNext()) > { > String stringPattern = (String) iter.next(); > boolean found; > if ((CONTAINS & getTestType()) > 0) > { > found = localCompilerMatcher > .contains(responseString, stringPattern); > } > else > { > found = localCompilerMatcher > .matches(responseString, stringPattern); > } > pass = not ? !found : found; > > if (!pass) > { > result.setFailure(true); > result.setFailureMessage( > "Test Failed, expected " + notMessage + failMessage + > stringPattern); > break; > } > } > if(pass) > { > result.setFailure(false); > } > result.setError(false); > } > catch(MalformedPatternException e) > { > result.setError(true); > result.setFailure(false); > result.setFailureMessage("Bad test configuration"+e); > } > return result; > } > > /** > * Performs regular expression matching and compiled regular expression > * pattern caching. > * > * This static member class is *not* thread-safe so it must be > * accessed from a java.lang.ThreadLocal instance for multi-thread usage. > * ThreadLocal causes slightly extra memory usage, but allows for faster > * thread-safe processing than synchronization would afford. > */ > public static class CompilerMatcher > { > private Perl5Compiler compiler = new Perl5Compiler(); > private Perl5Matcher matcher = new Perl5Matcher(); > private Map compiledPatterns = new HashMap(); > > /** > * Returns true if the compiled version of the patternString regular > * expression argument matches the aString argument. > */ > public boolean matches(String aString, String patternString) > throws MalformedPatternException > { > return this.matcher.matches(aString, > this.getTestPattern(patternString)); > } > > /** > * Returns true if the compiled version of the patternString regular > * expression argument is contained in the aString argument. > */ > public boolean contains(String aString, String patternString) > throws MalformedPatternException > { > return this.matcher.contains(aString, > this.getTestPattern(patternString)); > } > > /** > * Compiles and caches a regexp pattern for the given string pattern. > * This would be of no benefit (and may bloat memory usage) if the > * string pattern arg is never the same. But for this usage that > * won't be the case. > */ > private Pattern getTestPattern(String stringPattern) > throws MalformedPatternException > { > Pattern pattern = (Pattern) compiledPatterns.get(stringPattern); > if (pattern == null) > { > pattern = compiler.compile(stringPattern); > compiledPatterns.put(stringPattern, pattern); > log.debug("Compiled and cached a pattern: '" + stringPattern + > "' - " + Thread.currentThread()); > } > return pattern; > } > } > > > ********************************************************************** > This email and any files transmitted with it are confidential and > intended solely for the use of the individual or entity to whom they > are addressed. If you have received this email in error please notify > the system manager. > ********************************************************************** > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>