jsalvata 2003/01/02 19:04:38
Modified: src/components/org/apache/jmeter/assertions
ResponseAssertion.java
Log:
Made the ResponseAssertion thread-safe. Added test for this.
Revision Changes Path
1.2 +128 -49
jakarta-jmeter/src/components/org/apache/jmeter/assertions/ResponseAssertion.java
Index: ResponseAssertion.java
===================================================================
RCS file:
/home/cvs/jakarta-jmeter/src/components/org/apache/jmeter/assertions/ResponseAssertion.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ResponseAssertion.java 11 Aug 2002 19:24:39 -0000 1.1
+++ ResponseAssertion.java 3 Jan 2003 03:04:38 -0000 1.2
@@ -2,7 +2,7 @@
* ====================================================================
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,15 +60,20 @@
import org.apache.jmeter.config.ConfigElement;
import org.apache.jmeter.testelement.AbstractTestElement;
-import org.apache.oro.text.regex.*;
+import org.apache.oro.text.PatternCacheLRU;
+import org.apache.oro.text.MalformedCachePatternException;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
+import org.apache.oro.text.regex.Pattern;
/************************************************************
* Title: Jakarta-JMeter Description: Copyright: Copyright (c) 2001 Company:
* Apache
*
- *@author Michael Stover
- *@created $Date$
- *@version 1.0
+ * @author Michael Stover
+ * @author <a href="mailto:[EMAIL PROTECTED]">Jonathan Carlson</a>
+ * @created $Date$
+ * @version $Revision$
***********************************************************/
public class ResponseAssertion extends AbstractTestElement implements Serializable,
Assertion
@@ -86,8 +91,17 @@
public final static int MATCH = 1 << 0;
public final static int CONTAINS = 1 << 1;
public final static int NOT = 1 << 2;
- private transient static Perl5Compiler compiler = new Perl5Compiler();
- private transient static Perl5Matcher matcher = new Perl5Matcher();
+
+ private transient static ThreadLocal matcher =
+ new ThreadLocal()
+ {
+ protected Object initialValue()
+ {
+ return new Perl5Matcher();
+ }
+ };
+ private transient PatternCacheLRU patternCache =
+ new PatternCacheLRU(1000, new Perl5Compiler());
/************************************************************
* !ToDo (Constructor description)
@@ -278,50 +292,115 @@
setTestType(getTestType() & (NOT ^ (CONTAINS | MATCH | NOT)));
}
- private AssertionResult evaluateResponse(SampleResult response)
- {
- boolean pass = true;
- boolean not = (NOT & getTestType()) > 0;
- AssertionResult result = new AssertionResult();
- try
- {
- Iterator iter = getTestStrings().iterator();
- while (iter.hasNext())
- {
- String pattern = (String)iter.next();
- if ((CONTAINS & getTestType()) > 0)
- {
- pass = pass && (not ? !matcher.contains(new
String(response.getResponseData()),
- compiler.compile(pattern)) :
- matcher.contains(new
String(response.getResponseData()),
- compiler.compile(pattern)));
- }
- else
- {
- pass = pass && (not ? !matcher.matches(new
String(response.getResponseData()),
- compiler.compile(pattern)) :
- matcher.matches(new
String(response.getResponseData()),
- compiler.compile(pattern)));
- }
- if (!pass)
- {
- result.setFailure(true);
- result.setFailureMessage("Test Failed,
expected " + notMessage + failMessage + pattern);
- break;
- }
- }
- if(pass)
- {
- result.setFailure(false);
- }
- result.setError(false);
+ /**
+ * 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();
+ String responseString = new String(response.getResponseData());
+
+ try
+ {
+ // Get the Matcher for this thread
+ Perl5Matcher localMatcher = (Perl5Matcher)matcher.get();
+
+ Iterator iter = getTestStrings().iterator();
+ while (iter.hasNext())
+ {
+ String stringPattern= (String) iter.next();
+ Pattern pattern = patternCache.getPattern(stringPattern);
+ boolean found;
+ if ((CONTAINS & getTestType()) > 0)
+ {
+ found = localMatcher.contains(responseString, pattern);
}
- catch(MalformedPatternException e)
+ else
{
- result.setError(true);
- result.setFailure(false);
- result.setFailureMessage("Bad test configuration"+e);
+ found = localMatcher.matches(responseString, pattern);
}
- return result;
+ 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 (MalformedCachePatternException e)
+ {
+ result.setError(true);
+ result.setFailure(false);
+ result.setFailureMessage("Bad test configuration"+e);
+ }
+
+ return result;
+ }
+
+ public static class Test extends junit.framework.TestCase
+ {
+ int threadsRunning;
+ int failed;
+
+ public Test(String name)
+ {
+ super(name);
+ }
+
+ public void testThreadSafety() throws Exception
+ {
+ Thread[] threads= new Thread[100];
+ for (int i= 0; i < threads.length; i++) {
+ threads[i]= new TestThread();
+ }
+ failed= 0;
+ for (int i= 0; i < threads.length; i++) {
+ threads[i].start();
+ threadsRunning++;
+ }
+ synchronized (this)
+ {
+ while (threadsRunning>0) wait();
+ }
+ assertEquals(failed, 0);
+ }
+
+ class TestThread extends Thread
+ {
+ static final String TEST_STRING= "D�bale arroz a la zorra el abad.";
+ static final String TEST_PATTERN= ".*�.*\\.";
+ public void run()
+ {
+ ResponseAssertion assertion= new ResponseAssertion(
+ RESPONSE_DATA, CONTAINS, TEST_PATTERN);
+ SampleResult response= new SampleResult();
+ response.setResponseData(TEST_STRING.getBytes());
+ for (int i= 0; i< 100; i++) {
+ AssertionResult result;
+ result= assertion.evaluateResponse(response);
+ if (result.isFailure() || result.isError()) {
+ failed++;
+ }
+ }
+ synchronized(Test.this) {
+ threadsRunning--;
+ Test.this.notify();
+ }
+ }
}
+ }
+
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>