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]>

Reply via email to