Success! The ORO Perl5Matcher is not thread-safe. I checked the mailing list and
found some comments about Perl5Matcher needing to be accessed via a ThreadLocal
instance in mult-threaded situations.
This is what I did to ResponseAssertion to fix my problem:
1) I changed the "matcher" static field definition to this:
public transient static ThreadLocal matcher =
new ThreadLocal()
{
protected Object initialValue()
{
return new Perl5Matcher();
}
};
2) The whole inside of the try block of the #evaluateResponse(SampleResult) method is
below. (Sorry, I'm not real swift with diff yet and I can't access CVS anyways --
probably due to our firewall). Some of the changes were for efficiency and
code-readability -- like converting the responseData to a String only once. I am also
rather bothered by the fact that each pattern has to be recompiled all the time. The
patterns really should be compiled once and put into a ThreadLocal variable as well
(or they can be compiled with the Perl5Compiler.READ_ONLY_MASK flag and cached), but I
felt that would involve too many changes for this e-mail.
String responseString = new String(response.getResponseData());
// Get the matcher for this thread
Perl5Matcher localMatcher = (Perl5Matcher) this.matcher.get();
Iterator iter = getTestStrings().iterator();
while (iter.hasNext())
{
String pattern = (String)iter.next();
Pattern compiledPattern = compiler.compile(pattern);
boolean found;
if ((CONTAINS & getTestType()) > 0)
{
found = localMatcher.contains(responseString, compiledPattern);
}
else
{
found = localMatcher.matches(responseString, compiledPattern);
}
pass = not ? !found : found;
if (!pass)
{
result.setFailure(true);
result.setFailureMessage(
"Test Failed, expected " + notMessage + failMessage +
pattern);
break;
}
}
if(pass)
{
result.setFailure(false);
}
result.setError(false);
Thanks for your help and suggestions! This really was a serious problem, at least for
me. I'm guessing it hasn't been found before because most multi-threaded stress-tests
don't use the response assertion mechanism.
I'm using it with multiple threads to make sure the user data I entered is valid
before I start doing stress tests. Then I'll disable the response assertions for the
real stress test, although if they are efficient enough I'd like to leave them on to
let me know if the app starts flaking out under load. Otherwise I could be getting
errors and never knowing it (granted, I'd probably be better off just checking the
server logs, however at least one problem I recently found didn't involve an exception
situation).
Thanks again! Let me know when this can be incorporated into a version or release.
The nightly builds directory hasn't been updated since before Halloween.
Jonathan
**********************************************************************
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]>