tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@apache.org
Subject cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/test/matchers GoldenMatch.java HeaderMatch.java HttpStatusMatch.java ResponseMatch.java ResponseMatchFile.java
Date Fri, 09 Feb 2001 03:48:17 GMT
costin      01/02/08 19:48:17

  Modified:    src/share/org/apache/tomcat/util/test GTest.java Header.java
                        HttpClient.java Parameter.java TestDefaults.java
  Added:       src/share/org/apache/tomcat/util/test Cookie.java
                        HttpRequest.java HttpResponse.java Matcher.java
                        Properties.java
               src/share/org/apache/tomcat/util/test/matchers
                        GoldenMatch.java HeaderMatch.java
                        HttpStatusMatch.java ResponseMatch.java
                        ResponseMatchFile.java
  Removed:     src/share/org/apache/tomcat/util/test DefaultMatcher.java
                        Response.java
  Log:
  Few changes in the GTest to simplify the test writing. The code is more
  modular and extensible. All old tests should work fine, but more
  capabilities are available:
  - easy syntax for adding parameters ( both POST and GET - even for the
  same request )
  - multiple tests per request, better organization of matchers
  - adding new matchers should be easy ( and fun )
  
  Note that the original GTest tag will be used for backward compatibility
  ( it has few big limitations that can't be resolved with the same syntax
  - it's very hard to match multiple strings in the response, headers,
  it requires you to type the full request, etc )
  
  Revision  Changes    Path
  1.10      +103 -131  jakarta-tomcat/src/share/org/apache/tomcat/util/test/GTest.java
  
  Index: GTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/test/GTest.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- GTest.java	2001/02/07 06:41:33	1.9
  +++ GTest.java	2001/02/09 03:48:15	1.10
  @@ -62,13 +62,16 @@
   import java.io.*;
   import java.util.*;
   import java.net.*;
  +import org.apache.tomcat.util.test.matchers.*;
   
  -
  -/** Test a web application. Will send a http request and
  +/** Original tester for a web application. Will send a http request and
       verify the response code, compare the response with a golden
       file or find strings.
   
       This class is using the well-known ant patterns.
  +
  +    @deprecated Use HttpClient instead. This class has very limited
  +                support for multiple matchers, requests, etc.
   */
   public class GTest  {
       // Defaults
  @@ -78,21 +81,22 @@
       static boolean failureOnly=false;
   
       // all test results will be available
  -    static Vector testResults=new Vector();
  -    static Vector testFailures=new Vector();
  -    static Vector testSuccess=new Vector();
       static Hashtable testProperties=new Hashtable();
   
       // Instance variables
  -    
  +
  +    // The "real" thing.
  +    // GTest is here to support the old ( and simpler ) syntax .
  +    // The real work is done in HttpClient, which is a lot more
  +    // powerfull. For example it can handle multiple requests and
  +    // matches, etc
       HttpClient httpClient=new HttpClient();
  -    Vector matchers=new Vector();
  -    //DefaultMatcher matcher=new DefaultMatcher();
  -    Body comment=null;
  +
  +    // Gtest supports only one request. 
  +    HttpRequest httpRequest=new HttpRequest();
  +
       String failMessage="";
       
  -    String description="No description";
  -
       PrintWriter out=null;
       String outType=null;
       int debug=-1;
  @@ -100,8 +104,9 @@
       boolean result=false;
       
       public GTest() {
  -	//matcher.setDebug( debug );
   	httpClient.setDebug( debug );
  +	httpClient.addHttpRequest( httpRequest );
  +	//	httpClient.addMatcher( matcher );
       }
   
       // -------------------- Defaults --------------------
  @@ -126,21 +131,21 @@
        *  that were run.
        */
       public static Vector getTestResults() {
  -	return testResults;
  +	return HttpClient.getTestResults();
       }
   
       /** Vector of GTest elements, containing all test instances
        *  that were run and failed.
        */
       public static Vector getTestFailures() {
  -	return testFailures;
  +	return HttpClient.getTestFailures();
       }
   
       /** Vector of GTest elements, containing all test instances
        *  that were run and failed.
        */
       public static Vector getTestSuccess() {
  -	return testSuccess;
  +	return HttpClient.getTestSuccess();
       }
   
       /** Various global test propertis
  @@ -174,64 +179,35 @@
   	failureOnly=Boolean.valueOf(e).booleanValue();   
       }
   
  -    // -------------------- Ant patterns --------------------
  -
  -    public HttpClient createHttpClient() {
  -	return httpClient;
  -    }
  -
  -    public void addHttpClient(HttpClient c) {
  -	httpClient=c;
  -    }
  -
  -    public void addDefaultMatcher( DefaultMatcher m ) {
  -	matchers.addElement( m );
  -	//	matcher=m;
  -    }
  -
  -    public Body createComment() {
  -	comment=new Body();
  -	return comment;
  -    }
       // -------------------- Getters --------------------
   
       public HttpClient getHttpClient() {
   	return httpClient;
       }
  -    
  -//     public DefaultMatcher getMatcher() {
  -// 	return matcher;
  -//     }
   
       public String getComment() {
  -	if(comment==null) return "";
  -	return comment.getText();
  +	return httpClient.getComment();
       }
  -    
  +
       // -------------------- Local properties --------------------
       /** Description should be in <test description=""/>
        */
       public String getDescription() {
  -	if( comment!=null) return comment.getText();
  -	return description;
  +	return httpClient.getComment();
       }
   
       public void setDescription(String description) {
  -	this.description=description;
  +	httpClient.setDescription(description);
       }
   
       public String getMatchDescription() {
  -	StringBuffer sb=new StringBuffer();
  -	for( int i=0; i<matchers.size(); i++ ) {
  -	    DefaultMatcher m=(DefaultMatcher)matchers.elementAt( i );
  -	    if( i!=0 ) sb.append( " && " );
  -	    sb.append( m.getTestDescription());
  -	}
  -	return sb.toString();
  +	Matcher m=httpClient.getFailingMatch();
  +	if( m==null ) return "";
  +	return m.getTestDescription();
       }
   
       public String getFailureMessage() {
  -	return failMessage;
  +	return httpClient.getFailureMessage();
       }
       
       /** Display debug info
  @@ -244,89 +220,91 @@
   
       // -------------------- Client properties --------------------
       public void setHost(String h) {
  -	httpClient.setHost(h);
  +	httpRequest.setHost(h);
       }
       
       public void setPort(String portS) {
  -	httpClient.setPort( portS );
  +	httpRequest.setPort( portS );
       }
   
       /** Set the port as int - different name to avoid confusing ant
        */
       public void setPortInt(int i) {
  -	httpClient.setPortInt(i);
  +	httpRequest.setPortInt(i);
       }
   
       /** Do a POST with the specified content
        */
       public void setContent(String s) {
  -	httpClient.setContent(s);
  +	httpRequest.setContent(s);
       }
   
       /** Request line ( will have the host and context path prefix)
        */
       public void setRequest( String s ) {
  -	httpClient.setRequestLine(s);
  +	httpRequest.setRequestLine(s);
       }
       
       /** Send additional headers
        *  The value is a "|" separated list of headers to send
        */
       public void setHeaders( String s ) {
  -	httpClient.setHeaders( s );
  +	httpRequest.setHeaders( s );
       }
   
       // -------------------- Matcher properties --------------------
   
       // @deprecated Use defaultMatcher childs, this allow only one test !!!
   
  +    // GTest supports 5 different matches in a single element.
  +
  +    boolean exactMatch=false;
  +    boolean magnitude=true;
  +    String goldenFile;
  +    String expectedHeader;
  +    String responseMatch;
  +    String responseMatchFile;
  +    String returnCode;
       
  -    public void setExactMatch(String exact) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setExactMatch(exact);
  +    public void setExactMatch(boolean exact) {
  +	exactMatch=exact;
       }
   
       /** True if this is a positive test, false for negative
        */
  -    public void setMagnitude( String magnitudeS ) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setMagnitude( magnitudeS );
  +    public void setMagnitude( boolean m ) {
  +	magnitude=m;
       }
   
       /** Compare with the golden file
        */
       public void setGoldenFile( String s ) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setGoldenFile(s);
  +	goldenFile=s;
       }
   
       /** Verify that response includes the expected headers
        *  The value is a "|" separated list of headers to expect.
        */
       public void setExpectHeaders( String s ) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setExpectHeaders( s );
  +	expectedHeader=s;
       }
   
       /** Verify that response match the string
        */
       public void setResponseMatch( String s ) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setResponseMatch( s );
  +	responseMatch=s;
       }
   
       /** Verify that response matches a list of strings in a file
        */
       public void setResponseMatchFile( String s ) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setResponseMatchFile( s );
  +	responseMatchFile=s;
       }
   
       /** Verify the response code
        */
       public void setReturnCode( String s ) {
  -	if( matchers.size() > 0 )
  -	    ((DefaultMatcher)matchers.elementAt(0)).setReturnCode( s );
  +	returnCode=s;
       }
   
       // -------------------- Execute the request --------------------
  @@ -338,53 +316,68 @@
   	    if( outType==null) outType=defaultOutType;
   	    if( debug==-1) debug=defaultDebug;
   
  +	    initMatchers();
   	    httpClient.execute();
  -	    Response resp=httpClient.getResponse();
  +	    HttpResponse resp=httpRequest.getHttpResponse();
   
  -	    result=true;
  -	    for( int i=0; i< matchers.size(); i++ ) {
  -		DefaultMatcher matcher=(DefaultMatcher)matchers.elementAt(i);
  -		matcher.setResponse( resp );
  -		matcher.execute();
  -		boolean testResult=matcher.getResult();
  -		if( ! testResult ) {
  -		    result=false;
  -		    failMessage=matcher.getMessage();
  -		    break;
  -		}
  -	    }
  -	    
  -	    // don't print OKs
  -	    if( result && failureOnly ) return;
  +	    result=httpClient.getResult();
   
   	    if( "text".equals(outType) )
   		textReport();
   	    if( "html".equals(outType) )
   		htmlReport();
  -	    if( "xml".equals(outType) )
  -		xmlReport();
   	} catch(Exception ex ) {
   	    // no exception should be thrown in normal operation
   	    ex.printStackTrace();
   	}
   
  -	// after execute() is done, add the test result to the list
  -	testResults.addElement( this );
  -	if( !result )
  -	    testFailures.addElement( this );
  -	else
  -	    testSuccess.addElement( this );
       }
   
       
       // -------------------- Internal methods --------------------
   
  +    private void initMatchers( ) {
  +	if( goldenFile != null ) {
  +	    GoldenMatch gm=new GoldenMatch();
  +	    gm.setFile( goldenFile );
  +	    gm.setExactMatch( exactMatch );
  +	    gm.setExpectedResult( magnitude );
  +	    httpClient.addMatcher( gm );
  +	}
  +	if( expectedHeader != null ) {
  +	    HeaderMatch hm=new HeaderMatch();
  +	    hm.setExpectHeaders( expectedHeader );
  +	    hm.setExpectedResult( magnitude );
  +	    httpClient.addMatcher( hm );
  +	}
  +
  +	if( responseMatch != null ) {
  +	    ResponseMatch rm=new ResponseMatch();
  +	    rm.setMatch( responseMatch );
  +	    rm.setExpectedResult( magnitude );
  +	    httpClient.addMatcher( rm );
  +	}
  +	
  +	if( responseMatchFile != null ) {
  +	    ResponseMatchFile rf=new ResponseMatchFile();
  +	    rf.setFile( responseMatchFile );
  +	    rf.setExpectedResult( magnitude );
  +	    httpClient.addMatcher( rf );
  +	}
  +	if( returnCode != null ) {
  +	    HttpStatusMatch sm=new HttpStatusMatch();
  +	    sm.setMatch( returnCode );
  +	    sm.setExpectedResult( magnitude );
  +	    httpClient.addMatcher(sm );
  +	}
  +    }
  +    
       private void textReport() {
   	String msg=null;
  -	if(  "No description".equals( description )) 
  -	    msg=" (" + httpClient.getRequestLine() + ")";
  +	if(  "".equals( getDescription() )) 
  +	    msg=" (" + httpRequest.getRequestLine() + ")";
   	else
  -	    msg=description + " (" + httpClient.getRequestLine() + ")";
  +	    msg=getDescription() + " (" + httpRequest.getRequestLine() + ")";
   
   	if( result ) 
   	    out.println("OK " +  msg );
  @@ -396,7 +389,7 @@
       }
   
       private void htmlReport() {
  -	String uri=httpClient.getURI();
  +	String uri=httpRequest.getURI();
   	if( uri!=null )
   	    out.println("<a href='" + uri + "'>");
   	if( result )
  @@ -407,10 +400,10 @@
   	    out.println("</a>");
   
   	String msg=null;
  -	if(  "No description".equals( description )) 
  -	    msg=" (" + httpClient.getRequestLine() + ")";
  +	if(  "".equals( getDescription() )) 
  +	    msg=" (" + httpRequest.getRequestLine() + ")";
   	else
  -	    msg=description + " (" + httpClient.getRequestLine() + ")";
  +	    msg=getDescription() + " (" + httpRequest.getRequestLine() + ")";
   
   	out.println( msg );
   	
  @@ -426,11 +419,11 @@
   	}
   
   	if( ! result && debug > 0 ) {
  -	    out.println("<b>Request: </b><pre>" + httpClient.getFullRequest());
  +	    out.println("<b>Request: </b><pre>" + httpRequest.getFullRequest());
   	    out.println("</pre><b>Response:</b> " +
  -			httpClient.getResponse().getResponseLine());
  +			httpRequest.getHttpResponse().getResponseLine());
   	    out.println("<br><b>Response headers:</b><br>");
  -	    Hashtable headerH=httpClient.getResponse().getHeaders();
  +	    Hashtable headerH=httpRequest.getHttpResponse().getHeaders();
   	    Enumeration hE=headerH.elements();
   	    while( hE.hasMoreElements() ) {
   		Header h=(Header) hE.nextElement();
  @@ -438,32 +431,11 @@
   			    h.getValue() + "<br>");
   	    }
   	    out.println("<b>Response body:</b><pre> ");
  -	    out.println(httpClient.getResponse().getResponseBody());
  +	    out.println(httpRequest.getHttpResponse().getResponseBody());
   	    out.println("</pre>");
   	}
  -
  -	Throwable ex=httpClient.getResponse().getThrowable();
  -	if( ex!=null) {
  -	    out.println("<b>Exception</b><pre>");
  -	    ex.printStackTrace(out);
  -	    out.println("</pre><br>");
  -	}
  -	out.flush();
  -    }
  -
  -    private void xmlReport() {
  -	String msg=null;
  -	if(  "No description".equals( description )) 
  -	    msg=" (" + httpClient.getRequestLine() + ")";
  -	else
  -	    msg=description + " (" + httpClient.getRequestLine() + ")";
  -
  -	if(result) 
  -	    out.println("OK " + msg );
  -	else 
  -	    out.println("FAIL " + msg );
   
  -	Throwable ex=httpClient.getResponse().getThrowable();
  +	Throwable ex=httpRequest.getHttpResponse().getThrowable();
   	if( ex!=null) {
   	    out.println("<b>Exception</b><pre>");
   	    ex.printStackTrace(out);
  
  
  
  1.4       +2 -2      jakarta-tomcat/src/share/org/apache/tomcat/util/test/Header.java
  
  Index: Header.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/test/Header.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Header.java	2001/01/28 19:53:11	1.3
  +++ Header.java	2001/02/09 03:48:15	1.4
  @@ -141,14 +141,14 @@
       }
   
   
  -    public static void parseHeadersAsString( String s, Hashtable headers ) {
  +    public static void parseHeadersAsString( String s, Vector headers ) {
   	StringTokenizer st=new StringTokenizer( s, "|");
   	while( st.hasMoreTokens() ) {
   	    String tok=st.nextToken();
   	    Header h=new Header();
   	    h.parseHeaderLine( tok );
   	    if( h.getName() !=null )
  -		headers.put( h.getName(), h );
  +		headers.addElement( h );
   	}
       }
   
  
  
  
  1.7       +139 -215  jakarta-tomcat/src/share/org/apache/tomcat/util/test/HttpClient.java
  
  Index: HttpClient.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/test/HttpClient.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- HttpClient.java	2001/02/07 06:41:33	1.6
  +++ HttpClient.java	2001/02/09 03:48:15	1.7
  @@ -58,6 +58,7 @@
    */ 
   package org.apache.tomcat.util.test;
   
  +import org.apache.tomcat.util.test.matchers.*;
   import java.net.*;
   import java.io.*;
   import java.util.*;
  @@ -65,55 +66,28 @@
   
   
   /**
  - *  Part of GTest - send a Http request. This tool gives a lot 
  - *  of control over the request, and is usable with ant ( testing
  - *  is also a part of the build process :-) or other xml-tools
  - *  using similar patterns.
  - *
  - *  
  + *  HttpClient can send requests and execute matchers against the request.
  + *  This is the main tool that is used to test tomcat's web applications.
  + *  Typical use:
  + *  <pre>
  + *      <httpClient>
  + *        <request/>
  + *        <matcher/>
  + *      </httpClient>
  + *  </pre>
  + *  Part of GTest - send a Http request. 
    */
   public class HttpClient {
  -    // Defaults
  -    static String defaultHost="localhost";
  -    static int defaultPort=8080;
  -    static int defaultDebug=0;
  -    static String defaultProtocol="HTTP/1.0";
  -
  -    static Hashtable clients=new Hashtable();
  -    
  -    // Instance variables
  -
  +    HttpRequest firstRequest=null;
  +    Vector actions=new Vector();
       String id;
  -    // Instance variables
  -    String host=null;
  -    int port=-1;
  -
  -    int debug=defaultDebug;
  -
  -    String method="GET";
  -    String protocol=null;
  -    String path;
  -    
  -    String requestLine;
  -    Hashtable requestHeaders=new Hashtable();
  -    Vector headerVector=new Vector();// alternate
  -    Body body;
  -    
  -    String fullRequest;
  +    int debug=0;
  +    Body comment=null;
  +    boolean success=true;
       
  -    // Response resulted from this request
  -    Response response=new Response();
  -    static String CRLF="\r\n";
  -
       public HttpClient() {
       }
   
  -    /** Return one of the "named" clients that have been executed so far.
  -     */
  -    public static Hashtable getHttpClients() {
  -	return clients;
  -    }
  -
       /** Set an unique id to this request. This allows it to be
        *  referenced later, for complex tests/matchers that look
        * 	at multiple requests.
  @@ -122,225 +96,145 @@
   	this.id=id;
       }
   
  -    /** Server that will receive the request
  +    /** Display debug info
        */
  -    public void setHost(String h) {
  -	this.host=h;
  +    public void setDebug( int d ) {
  +	debug=d;
       }
  -
  -    /** 
  +    
  +    /** Add a request that will be executed.
        */
  -    public void setMethod(String h) {
  -	this.method=h;
  +    public void addHttpRequest( HttpRequest b ) {
  +	b.setHttpClient( this );
  +	if( firstRequest == null ) firstRequest=b;
  +	actions.addElement( b );
       }
   
  -    /** The port used to send the request
  -     */
  -    public void setPort(String portS) {
  -	this.port=Integer.valueOf( portS).intValue();
  +    public Body createComment() {
  +	comment=new Body();
  +	return comment;
       }
   
  -    /** Set the port as int - different name to avoid confusing introspection
  -     */
  -    public void setPortInt(int i) {
  -	this.port=i;
  +    public String getComment() {
  +	if(comment==null) return "";
  +	return comment.getText();
       }
   
  -    /** Do a POST with the specified content.
  -     */
  -    public void setContent(String s) {
  -	body=new Body( s );
  +    public void setDescription( String s ) {
  +	comment=new Body( s );
       }
  +    
  +    // -------------------- Various matchers --------------------
   
  -    /** Add content to the request, for POST ( alternate method )
  +    /** Add a matcher.
        */
  -    public void addBody( Body b ) {
  -	body=b;
  +    public void addMatcher( Matcher m ) {
  +	m.setHttpClient( this );
  +	actions.addElement( m );
       }
   
  -    public void setProtocol( String s ) {
  -	protocol=s;
  -    }
  -    
  -    public void setPath( String s ) {
  -	path=s;
  -    }
  +    // XXX Ant is not able to handle generic addXXX, we need to add
  +    // individual methods for each matcher
   
  -    public void addHeader( String n, String v ) {
  -	requestHeaders.put(n, new Header( n, v) );
  +    public void addGoldenMatch( GoldenMatch m ) {
  +	addMatcher( m );
       }
  -
  -    /** Add a header to the request
  -     */
  -    public void addHeader( Header rh ) {
  -	headerVector.addElement( rh );
  +    public void addHeaderMatch( HeaderMatch m ) {
  +	addMatcher( m );
       }
  -
  -    /** Add headers - string representation, will be parsed
  -     *  The value is a "|" separated list of headers to expect.
  -     *  It's preferable to use the other 2 methods.
  -     */
  -    public void setHeaders( String s ) {
  -       requestHeaders=new Hashtable();
  -       Header.parseHeadersAsString( s, requestHeaders );
  +    public void addHttpStatusMatch( HttpStatusMatch m ) {
  +	addMatcher( m );
       }
  -
  -
  -    /** Add a parameter to the request
  -     *  XXX not implemented
  -     */
  -    public void addParameter( Parameter rp ) {
  +    public void addResponseMatch( ResponseMatch m ) {
  +	addMatcher( m );
       }
  -
  -    /** Display debug info
  -     */
  -    public void setDebug( int d ) {
  -	debug=d;
  -    }
  -
  -    /** Verbose request line - including method and protocol
  -     */
  -    public void setRequestLine( String s ) {
  -	this.requestLine=s;
  +    public void addResponseMatchFile( ResponseMatchFile m ) {
  +	addMatcher( m );
       }
       
  -    public String getRequestLine( ) {
  -	if( requestLine==null ) {
  -	    prepareRequest(); 
  -	    int idx=fullRequest.indexOf("\r");
  -	    if( idx<0 )
  -		requestLine=fullRequest;
  -	    else
  -		requestLine=fullRequest.substring(0, idx );
  -	}
  -	return requestLine;
  -    }
       
  -    /** Allow sending a verbose request
  -     */
  -    public void setFullRequest( String s ) {
  -	fullRequest=s;
  -    }
  +    // -------------------- Access to the actions --------------------
   
  -    public String getFullRequest() {
  -	return fullRequest;
  +    public HttpRequest getFirstRequest() {
  +	return firstRequest;
       }
   
  -    /** Alternate method for sending a verbose request
  -     */
  -    public void addText(String s ) {
  -	fullRequest=s;
  -    }
  +    // -------------------- Result --------------------
  +    Matcher failingMatcher=null;
   
  -    // -------------------- Access the response --------------------
  +    public Matcher getFailingMatch() {
  +	return failingMatcher;
  +    }
   
  -    public Response getResponse() {
  -	return response;
  +    public String getFailureMessage() {
  +	if( failingMatcher==null ) return "";
  +	return failingMatcher.getMessage();
       }
   
  +    public boolean getResult() {
  +	return success;
  +    }
  +    
       // -------------------- Execute the request --------------------
   
       public void execute() {
   	try {
  -	    dispatch();
  +	    Enumeration aE=actions.elements();
  +	    HttpRequest lastRequest=null;
  +	    while( aE.hasMoreElements() ) {
  +		Object action=aE.nextElement();
  +		if( action instanceof HttpRequest ) {
  +		    lastRequest=(HttpRequest)action;
  +		    dispatch(lastRequest);
  +		} else if( action instanceof Matcher ) {
  +		    Matcher matcher=(Matcher)action;
  +		    matcher.setHttpRequest( lastRequest );
  +		    matcher.setHttpResponse( lastRequest.getHttpResponse() );
  +		    matcher.execute();
  +		    boolean testResult=matcher.getResult();
  +		    if( ! testResult ) {
  +			success=false;
  +			failingMatcher=matcher;
  +			break;
  +		    }
  +		}
  +	    }
   	} catch(Exception ex ) {
   	    ex.printStackTrace();
   	}
   	if( id!=null )
   	    clients.put( id, this );
  -    }
  -
  -    /** 
  -     */
  -    private void prepareRequest() 
  -    {
  -	// explicitely set
  -	if( fullRequest != null ) return;
  -
  -	// use the existing info to compose what will be sent to the
  -	// server
  -	StringBuffer sb=new StringBuffer();
  -	if( requestLine != null ) 
  -	    sb.append(requestLine);
  -	else {
  -	    sb.append( method ).append(" ").append(path).append(" ");
  -	    sb.append(protocol);
  -	    requestLine=sb.toString();
  -	}
   
  -	sb.append(CRLF);
  -
  -	// We may test HTTP0.9 behavior. If it's post 1.0, it needs
  -	// a LF
  -	if( requestLine.indexOf( "HTTP/1." ) <0 ) {
  -	    fullRequest=sb.toString();
  -	    return; // nothing to add
  -	}
  -
  -	String contentL=null;
  -
  -	Enumeration en=headerVector.elements();
  -	while( en.hasMoreElements()) {
  -	    Header rh=(Header)en.nextElement();
  -	    requestHeaders.put( rh.getName(), rh );
  -	}
  -	 
  -	// headers
  -	Enumeration headersE=requestHeaders.elements();
  -	while( headersE.hasMoreElements() ) {
  -	    Header h=(Header)headersE.nextElement();
  -	    sb.append(h.getName()).append(": ");
  -	    sb.append(h.getValue()).append( CRLF );
  -	    if( "Content-Length".equals( h.getName() )) {
  -		contentL=h.getValue();
  -	    }
  -	}
  -	if( requestHeaders.get("Host") == null ) {
  -	    sb.append("Host: ").append(host ).append( CRLF );
  -	}
  -	
  -	// If we have a body
  -	if( body != null) {
  -	    // If set explicitely ( maybe we're testing bad POSTs )
  -	    if( contentL==null ) {
  -		sb.append("Content-Length: ").append( body.getBody().length());
  -		sb.append(CRLF).append( CRLF);
  -	    }
  -	    
  -	    sb.append(body.getBody());
  -	    // no /n at the end -see HTTP specs!
  -	    // If we want to test bad POST - set Content-Length
  -	    // explicitely.
  -	} else {
  -	    sb.append( CRLF );
  -	}
  +	// after execute() is done, add the test result to the list
  +	testResults.addElement( this );
  +	if( !success )
  +	    testFailures.addElement( this.getFailingMatch() );
  +	else
  +	    testSuccess.addElement( this );
   
  -	// set the fullRequest
  -	fullRequest=sb.toString();
       }
   
       /** Invoke a request, set headers, responseLine, body
        *  We use plain socket ( instead of the more convenient URLConnection)
        *  because we want to check bad http, special strings, etc.
        */
  -    private void dispatch()
  +    private void dispatch(HttpRequest req)
   	throws Exception
       {
   	// connect
  -	if( host==null ) host=defaultHost;
  -	if( port==-1) port=defaultPort;
  -
  -	if( protocol==null ) protocol=defaultProtocol;
  -
  -	Socket s = new Socket( host, port);
  +	Socket s = new Socket( req.getHost(), req.getPort());
   	s.setSoLinger( true, 1000);
   
   	InputStream is=	s.getInputStream();
   	OutputStream os=s.getOutputStream();
   	OutputStreamWriter out=new OutputStreamWriter(os);
   	PrintWriter pw = new PrintWriter(out);
  +
  +	HttpResponse response=new HttpResponse();
  +	req.setHttpResponse( response );
   
  -	prepareRequest();
  +	req.prepareRequest();
  +	String fullRequest=req.getFullRequest();
   	if( debug > 5 ) {
   	    System.out.println("--------------------Sending " );
   	    System.out.println(fullRequest);
  @@ -455,18 +349,48 @@
   	// Convert the line to a String and return it
   	return (sb.toString());
       }
  +
  +    // -------------------- Client registry --------------------
  +    // all test results will be available
  +    static Vector testResults=new Vector();
  +    static Vector testFailures=new Vector();
  +    static Vector testSuccess=new Vector();
  +
  +
  +    static Hashtable clients=new Hashtable();
   
  -    /** Return a URI (guessed) from the requestLine/fullRequest
  +    /** Return one of the "named" clients that have been executed so far.
        */
  -    public String getURI() {
  -	String toExtract=fullRequest;
  -	if( fullRequest==null ) toExtract=requestLine;
  -	if( toExtract==null ) return null;
  -
  -	if( ! toExtract.startsWith("GET")) return null;
  -	StringTokenizer st=new StringTokenizer( toExtract," " );
  -	st.nextToken(); // GET
  -	return st.nextToken();
  +    public static Hashtable getHttpClients() {
  +	return clients;
       }
  +
       
  +    /** Vector of GTest elements, containing all test instances
  +     *  that were run.
  +     */
  +    public static Vector getTestResults() {
  +	return testResults;
  +    }
  +
  +    /** Vector of GTest elements, containing all test instances
  +     *  that were run and failed.
  +     */
  +    public static Vector getTestFailures() {
  +	return testFailures;
  +    }
  +
  +    /** Vector of GTest elements, containing all test instances
  +     *  that were run and failed.
  +     */
  +    public static Vector getTestSuccess() {
  +	return testSuccess;
  +    }
  +
  +
  +    // --------------------
  +
  +    public String getMatchDescription() {
  +	return "";
  +    }
   }
  
  
  
  1.2       +35 -1     jakarta-tomcat/src/share/org/apache/tomcat/util/test/Parameter.java
  
  Index: Parameter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/test/Parameter.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Parameter.java	2001/01/20 19:42:09	1.1
  +++ Parameter.java	2001/02/09 03:48:15	1.2
  @@ -69,9 +69,43 @@
    * 
    */
   public class Parameter {
  -
  +    private String name;
  +    private String value;
  +    private String type;
  +    
       public Parameter() {}
   
  +    public void setName( String n ) {
  +	name=n;
  +    }
  +
  +    public String getName() {
  +	return name;
  +    }
  +    
  +    public void setValue( String v ) {
  +	value=v;
  +    }
  +
  +    public String getValue() {
  +	return value;
  +    }
  +    
  +    /** POST or GET - if not set the current method's type will be
  +     *  used. You can set it to force GET parameters on POST requests
  +     */
  +    public void setType( String t ) {
  +	type=t;
  +    }
  +
  +    public String getType() {
  +	return type;
  +    }
  +    
  +    public String getType(String def) {
  +	if( type==null ) return def;
  +	return type;
  +    }
       
   
   }
  
  
  
  1.2       +3 -3      jakarta-tomcat/src/share/org/apache/tomcat/util/test/TestDefaults.java
  
  Index: TestDefaults.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/test/TestDefaults.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestDefaults.java	2001/01/21 20:10:39	1.1
  +++ TestDefaults.java	2001/02/09 03:48:15	1.2
  @@ -73,15 +73,15 @@
   
       public void setHost( String s ) {
   	// I know, I'll add setters...
  -	HttpClient.defaultHost=s;
  +	HttpRequest.defaultHost=s;
       }
   
       public void setPort(int port ) {
  -	HttpClient.defaultPort=port;
  +	HttpRequest.defaultPort=port;
       }
   
       public void setProtocol( String proto ) {
  -	HttpClient.defaultProtocol=proto;
  +	HttpRequest.defaultProtocol=proto;
       }
   
       public void setDebug( int debug ) {
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/Cookie.java
  
  Index: Cookie.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  /**
   *  Part of GTest
   * 
   */
  public class Cookie {
      private String name;
      private String value;
      private int version;
      
      public Cookie() {}
  
      public void setName( String n ) {
  	name=n;
      }
  
      public String getName() {
  	return name;
      }
      
      public void setValue( String v ) {
  	value=v;
      }
  
      public String getValue() {
  	return value;
      }
      
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/HttpRequest.java
  
  Index: HttpRequest.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  import org.apache.tomcat.util.Base64;
  
  /**
   *  Part of GTest - defines a Http request. This tool gives a lot 
   *  of control over the request, and is usable with ant ( testing
   *  is also a part of the build process :-) or other xml-tools
   *  using similar patterns.
   *
   *  
   */
  public class HttpRequest {
      // Defaults
      static String defaultHost="localhost";
      static int defaultPort=8080;
      static int defaultDebug=0;
      static String defaultProtocol="HTTP/1.0";
      
      String id;
  
      String host=null;
      int port=-1;
  
      String method="GET";
      String protocol=null;
      String path;
      
      String requestLine;
  
      Vector headerVector=new Vector();
      Vector paramsV=new Vector();
      String user;
      String password;
      Body body;
  
      // Request body as it'll be sent
      String fullRequest;
      
      int debug=defaultDebug;
      HttpClient client=null;
      HttpResponse response=null;
      
  
      public HttpRequest() {
      }
  
      /** Associated response, set after executing the request
       */
      public void setHttpResponse(HttpResponse r) {
  	response=r;
      }
  
      public HttpResponse getHttpResponse() {
  	return response;
      }
  
  
      public void setHttpClient( HttpClient c ) {
  	client=c;
      }
  
      public HttpClient getHttpClient() {
  	return client;
      }
  
      /** Set an unique id to this request. This allows it to be
       *  referenced later, for complex tests/matchers that look
       * 	at multiple requests.
       */
      public void setId(String id) {
  	this.id=id;
      }
  
      /** Server that will receive the request
       */
      public void setHost(String h) {
  	this.host=h;
      }
  
      public String getHost() {
  	if( host==null ) host=defaultHost;
  	return host;
      }
      
      /** 
       */
      public void setMethod(String h) {
  	this.method=h;
      }
  
      /** The port used to send the request
       */
      public void setPort(String portS) {
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      /** Set the port as int - different name to avoid confusing introspection
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      public int getPort() {
  	if( port==-1) port=defaultPort;
  	return port;
      }
  
      public void setUser( String u ) {
  	this.user=u;
      }
  
      public void setPassword( String p ) {
  	password=p;
      }
      
      /** Do a POST with the specified content.
       */
      public void setContent(String s) {
  	body=new Body( s );
      }
  
      /** Add content to the request, for POST ( alternate method )
       */
      public void addBody( Body b ) {
  	body=b;
      }
  
      public void setProtocol( String s ) {
  	protocol=s;
      }
      
      public void setPath( String s ) {
  	path=s;
      }
  
      public void addHeader( String n, String v ) {
  	headerVector.addElement( new Header( n, v) );
      }
  
      /** Add a header to the request
       */
      public void addHeader( Header rh ) {
  	headerVector.addElement( rh );
      }
  
      /** Add headers - string representation, will be parsed
       *  The value is a "|" separated list of headers to expect.
       *  It's preferable to use the other 2 methods.
       */
      public void setHeaders( String s ) {
         Header.parseHeadersAsString( s, headerVector );
      }
  
  
      /** Add a parameter to the request
       */
      public void addParam( Parameter rp ) {
  	paramsV.addElement( rp );
      }
  
      /** Display debug info
       */
      public void setDebug( int d ) {
  	debug=d;
      }
  
      /** Verbose request line - including method and protocol
       */
      public void setRequestLine( String s ) {
  	this.requestLine=s;
      }
      
      public String getRequestLine( ) {
  	if( requestLine==null ) {
  	    prepareRequest(); 
  	    int idx=fullRequest.indexOf("\r");
  	    if( idx<0 )
  		requestLine=fullRequest;
  	    else
  		requestLine=fullRequest.substring(0, idx );
  	}
  	return requestLine;
      }
      
      /** Allow sending a verbose request
       */
      public void setFullRequest( String s ) {
  	fullRequest=s;
      }
  
      public String getFullRequest() {
  	return fullRequest;
      }
  
      /** Add content to the request, for POST ( alternate method )
       */
      public void addVerbose( Body b ) {
  	fullRequest=b.getBody();
      }
  
      /** Alternate method for sending a verbose request
       */
      public void addText(String s ) {
  	fullRequest=s;
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() {
  	prepareRequest();
      }
  
      boolean prepared=false;
      static String CRLF="\r\n";
      /** 
       */
      public void prepareRequest() 
      {
  	if( prepared ) return;
  	if( host==null ) host=defaultHost;
  	if( port==-1) port=defaultPort;
  	if( protocol==null ) protocol=defaultProtocol;
  	
  	prepared=true;
  	
  	if( id==null ) {
  	    id="Req" + getId();
  	}
  	registerHttpRequest( id, this );
  
  	// explicitely set - the rest doesn't matter
  	if( fullRequest != null ) return;
  
  	// use the existing info to compose what will be sent to the
  	// server
  	StringBuffer sb=new StringBuffer();
  	if( requestLine != null ) 
  	    sb.append(requestLine); // explicitely set 
  	else {
  	    sb.append( method ).append(" ").append(path);
  	    // all GET parameters
  	    boolean first=true;
  	    for( int i=0; i< paramsV.size(); i++ ) {
  		Parameter p=(Parameter)paramsV.elementAt(i);
  		if( "GET".equals( p.getType( method ) )) {
  		    if( first && (path.indexOf("?") <0) ) {
  			sb.append("?");
  			first=false;
  		    } else {
  			sb.append( "&" );
  		    }
  		    // not null? Encode ?
  		    sb.append(p.getName());
  		    sb.append("=");
  		    String v=p.getValue();
  		    if( v!=null) sb.append(v);
  		}
  	    }
  	    sb.append(" ").append(protocol);
  	    requestLine=sb.toString();
  	}
  
  	sb.append(CRLF);
  
  	// We may test HTTP0.9 behavior. If it's post 1.0, it needs
  	// a LF
  	if( requestLine.indexOf( "HTTP/1." ) <0 ) {
  	    fullRequest=sb.toString();
  	    return; // nothing to add
  	}
  
  	String contentL=null;
  	String hostHeader=null;
  	String contentType=null;
  	String authorization=null;
  
  	Enumeration headersE=headerVector.elements();
  	while( headersE.hasMoreElements() ) {
  	    Header h=(Header)headersE.nextElement();
  	    sb.append(h.getName()).append(": ");
  	    sb.append(h.getValue()).append( CRLF );
  	    if( "Content-Type".equals( h.getName() )) 
  		contentType=h.getValue();
  	    if( "Content-Length".equals( h.getName() )) 
  		contentL=h.getValue();
  	    if( "Host".equals( h.getName() )) 
  		hostHeader=h.getValue();
  	    if( "Authorization".equals( h.getName() )) 
  		authorization=h.getValue();
  	}
  	if( hostHeader == null && host!=null && ! "".equals(host)  ) {
  	    sb.append("Host: ").append( host ).append( CRLF );
  	}
  
  	// If we are in a POST and Parameters are specified -
  	// add the header and prepare the body
  	if( body==null && "POST".equals( method ) ) {
  	    // we may have POST parameters.
  	    StringBuffer bodySB=new StringBuffer();
  	    
  	    boolean first=true;
  	    for( int i=0; i< paramsV.size(); i++ ) {
  		Parameter p=(Parameter)paramsV.elementAt(i);
  		if( "POST".equals( p.getType( "POST") )) {
  		    if( ! first ) {
  			bodySB.append( "&" );
  		    }
  		    first=false;
  		    // not null? Encode ?
  		    bodySB.append(p.getName());
  		    bodySB.append("=");
  		    String v=p.getValue();
  		    if( v!=null) bodySB.append(v);
  		}
  	    }
  	    if( ! first ) {
  		// we had a post param and we constructed the body
  		if( contentType==null ) {
  		    sb.append( "Content-Type: ");
  		    sb.append( "application/x-www-form-urlencoded");
  		    sb.append(CRLF);
  		}
  		body= new Body( bodySB.toString());
  	    }
  	}
  
  	// Deal with authorization
  	if( authorization == null &&
  	    user!=null && password !=null ) {
  	    sb.append( "Authorization: Basic " );
  	    String token=user + ":" + password;
  	    sb.append( Base64.encode( token.getBytes() ));
  	    sb.append( CRLF );
  	}
  	
  	// If we have a body
  	if( body != null) {
  	    // If set explicitely ( maybe we're testing bad POSTs )
  	    if( contentL==null ) {
  		sb.append("Content-Length: ").append( body.getBody().length());
  		sb.append(CRLF).append( CRLF);
  	    }
  	    
  	    sb.append(body.getBody());
  	    // no /n at the end -see HTTP specs!
  	    // If we want to test bad POST - set Content-Length
  	    // explicitely.
  	} else {
  	    sb.append( CRLF );
  	}
  
  	// set the fullRequest
  	fullRequest=sb.toString();
      }
  
      /** Return a URI (guessed) from the requestLine/fullRequest
       */
      public String getURI() {
  	String toExtract=fullRequest;
  	if( fullRequest==null ) toExtract=requestLine;
  	if( toExtract==null ) return null;
  
  	if( ! toExtract.startsWith("GET")) return null;
  	StringTokenizer st=new StringTokenizer( toExtract," " );
  	st.nextToken(); // GET
  	return st.nextToken();
      }
  
      // -------------------- Repository for requet definitions ----------
      static int idCounter=0;
      static Hashtable allRequests=new Hashtable();
  
      public static synchronized int getId() {
  	return idCounter++;
      }
      
      /** Return one of the "named" clients that have been executed so far.
       */
      public static Hashtable getAllRequests() {
  	return allRequests;
      }
  
      public static void registerHttpRequest( String id, HttpRequest req ) {
  	allRequests.put( id, req );
      }
  
      public static HttpRequest getHttpRequest( String id ) {
  	return (HttpRequest)allRequests.get(id);
      }
  
      public static Enumeration getHttpRequests() {
  	return allRequests.keys();
      }
  
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/HttpResponse.java
  
  Index: HttpResponse.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  /**
   *  Part of GTest.
   * 
   */
  public class HttpResponse {
  
      String responseLine;
      String responseBody;
      Hashtable responseHeaders=new Hashtable();
      
      Throwable exception;
  
      public HttpResponse() {}
  
      /** Exception thrown during request execution
       */
      public void setThrowable( Throwable t ) {
  	exception=t;
      }
  
      public Throwable getThrowable() {
  	return exception;
      }
  
      
      /**
       * Response headers 
       */
      public Hashtable getHeaders() {
  	return responseHeaders;
      }
  
      public void setHeaders(Hashtable  v) {
  	this.responseHeaders = v;
      }
      
      
      /**
       * Get the value of responseBody - the content
       */
      public String getResponseBody() {
  	return responseBody;
      }
      
      public void setResponseBody(String  v) {
  	this.responseBody = v;
      }
      
      
      /**
       * Get the value of responseLine - the first line of the response
       */
      public String getResponseLine() {
  	return responseLine;
      }
      
      public void setResponseLine(String  v) {
  	this.responseLine = v;
      }
      
      
  
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/Matcher.java
  
  Index: Matcher.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  /**
     Part of the GTest application
  */
  public class Matcher {
      protected HttpResponse response;
      protected HttpRequest request;
      protected HttpClient client;
      protected boolean result=false;
      protected boolean magnitude=true; // expectedResult
      protected int debug=0;
      
      // If the matching fails, a description of what failed
      StringBuffer messageSB=new StringBuffer();
          
      public Matcher() {
      }
  
      // -------------------- General Properties --------------------
  
      /** Test description ( text representation of the test )
       */
      public String getTestDescription() {
  	return "";
      }
  
      public void setExpectedResult( boolean b ) {
  	magnitude=b;
      }
  
      public void setMagnitude( boolean b ) {
  	magnitude=b;
      }
  
      /** Display debug info
       */
      public void setDebug( int d ) {
  	debug=d;
      }
  
      /** Return a message describing the reason of the failure
       *  or the test log
       */
      public String getMessage() {
  	return messageSB.toString();
      }
  
      /** Add a message to the test log
       */
      protected void log(String s ) {
  	messageSB.append( s ).append("\r\n");
      }
  
      /** Result of the test
       */
      public boolean getResult() {
  	return result;
      }
      
      
      // -------------------- Client, request, response --------------------
      /** The test case
       */
      public void setHttpClient( HttpClient req ) {
  	client=req;
      }
  
      public HttpClient getHttpClient() {
  	return client;
      }
  
      /** The request that generated the response
       */
      public void setHttpRequest( HttpRequest req ) {
  	request=req;
      }
  
      
      public HttpRequest getHttpRequest() {
  	return request;
      }
  
      /** The response we'll match against
       */
      public void setHttpResponse( HttpResponse resp ) {
  	response=resp;
      }
  
      public HttpResponse getHttpResponse() {
  	return response;
      }
  
      // --------------------
  
      /** Execute the test
       */
      public void execute() {
      }
  
      
      
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/Properties.java
  
  Index: Properties.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test;
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  /**
   *  Part of GTest
   * 
   */
  public class Properties {
      Hashtable keys=new Hashtable();
      
      public Properties() {}
  
  
      
      /** Replace ${NAME} with the property value
       *  Reproduced from ant, without dependencies on Project. Should be
       *  part of a top-level tool set.
       */
      public static String replaceProperties(String value, Hashtable keys )
      {
          StringBuffer sb=new StringBuffer();
          int i=0;
          int prev=0;
          if( value==null ) return null;
          int pos;
          while( (pos=value.indexOf( "$", prev )) >= 0 ) {
              if(pos>0) {
                  sb.append( value.substring( prev, pos ) );
              }
              if( pos == (value.length() - 1)) {
                  sb.append('$');
                  prev = pos + 1;
              }
              else if (value.charAt( pos + 1 ) != '{' ) {
                  sb.append( value.charAt( pos + 1 ) );
                  prev=pos+2; 
              } else {
                  int endName=value.indexOf( '}', pos );
                  if( endName < 0 ) {
  		    // it's not a property..
  		    sb.append( value.substring( pos ));
  		    pos=value.length() -1;
                  }
                  String n=value.substring( pos+2, endName );
                  String v = (keys.containsKey(n)) ?
  		    (String) keys.get(n) :
  		    "${"+n+"}"; 
                  
                  sb.append( v );
                  prev=endName+1;
              }
          }
          if( prev < value.length() ) sb.append( value.substring( prev ) );
          return sb.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/matchers/GoldenMatch.java
  
  Index: GoldenMatch.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test.matchers;
  
  import org.apache.tomcat.util.test.*;
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  /**
   *  Check if the Resposne body matches a golden file.
   */
  public class GoldenMatch extends Matcher {
  
      // Match the body against a golden file
      String goldenFile;
  
      // ignore spaces ?
      boolean exactMatch=false;
  
  
      public GoldenMatch() {
      }
  
      // -------------------- 
  
      
      public void setExactMatch(boolean ex) {
  	exactMatch=ex;
      }
  
      /** Compare with the golden file
       */
      public void setFile( String s ) {
  	this.goldenFile=s;
      }
  
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
      public String getTestDescription() {
  	StringBuffer desc=new StringBuffer();
  	desc.append("( responseBody " );
  	if( exactMatch )
  	    desc.append( "equals file '" );
  	else
  	    desc.append( "like file '");
  	int idx=goldenFile.lastIndexOf("/");
  	String g=(idx>0) ? goldenFile.substring(idx) : goldenFile;
  	desc.append( goldenFile + "') ");
  
  	desc.append( " == " ).append( magnitude );
  	return desc.toString();
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() {
  	try {
  	    result=checkResponse( magnitude );
  	} catch(Exception ex ) {
  	    ex.printStackTrace();
  	    result=false;
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
  	String responseLine=response.getResponseLine();
  	Hashtable headers=response.getHeaders();
  	
          boolean responseStatus = true;
  	
  	String responseBody=response.getResponseBody();
  	    
  	// compare the body
  	if( goldenFile==null) return responseStatus;
  
  	// Get the expected result from the "golden" file.
  	StringBuffer expResult = getExpectedResult();
  	
  	// Compare the results and set the status
  	boolean cmp=true;
  	
  	if(exactMatch)
  	    cmp=compare(responseBody, expResult.toString() );
  	else
  	    cmp=compareWeek( responseBody, expResult.toString());
  	
  	if( cmp  != testCondition ) {
  	    responseStatus = false;
  	    log("ERROR (" + cmp + "," + testCondition + ")");
  	    log("====================Expecting: ");
  	    log(expResult.toString());
  	    log("====================Got:");
  	    log(responseBody);
  	    log("====================");
  	}	    
  	
  	return responseStatus;
      }
      
      // Parse a file into a String.
      private StringBuffer getExpectedResult()
  	throws IOException
      {
          StringBuffer expResult = new StringBuffer("NONE");
  
          try {
  	    InputStream in = new FileInputStream( goldenFile );
  	    return readBody ( in );
          } catch (Exception ex) {
              log("\tGolden file not found: " + goldenFile);
              return expResult;
          }
      }
  
  
      // Compare the actual result and the expected result.
      private boolean compare(String str1, String str2) {
  	if ( str1==null || str2==null) return false;
  	if ( str1.length() != str2.length() ) {
  	    log("Wrong size " + str1.length() +" " + str2.length() );
  	    return false;
  	}
  	
          for(int i=0; i<str1.length() ; i++ ) {
              if (str1.charAt( i ) != str2.charAt( i ) ) {
  		log("Error at " + i  + " " + str1.charAt(1) +
  				   str2.charAt(i));
                  return false;
              }
          }
  	return true;
      }
  
      // Compare the actual result and the expected result.
      // Original compare - ignores spaces ( because most
      // golden files are wrong !)
      private boolean compareWeek(String str1, String str2) {
   	if ( str1==null || str2==null) return false;
  	
          StringTokenizer st1=new StringTokenizer(str1);
          StringTokenizer st2=new StringTokenizer(str2);
  
          while (st1.hasMoreTokens() && st2.hasMoreTokens()) {
              String tok1 = st1.nextToken();
              String tok2 = st2.nextToken();
              if (!tok1.equals(tok2)) {
  		log("\tFAIL*** : Rtok1 = " + tok1 
                          + ", Etok2 = " + tok2);
                  return false;
              }
          }
  
          if (st1.hasMoreTokens() || st2.hasMoreTokens()) {
              return false;
          } else {
              return true;
          }
      }
  
      // XXX return byte [], fix the reading !!!!!
      StringBuffer readBody( InputStream input )
      {
  	StringBuffer sb = new StringBuffer();
  	while (true) {
  	    try {
  		int ch = input.read();
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			return (null);
  		    } else {
  			break;
  		    }
  		}
  		sb.append((char) ch);
  	    } catch(IOException ex ) {
  		return sb;
  	    }
  	}
          return sb;
      }
  
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/matchers/HeaderMatch.java
  
  Index: HeaderMatch.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test.matchers;
  
  import org.apache.tomcat.util.test.*;
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  /** Check if the response has ( or has not ) some headers
   */
  public class HeaderMatch extends Matcher {
      String name;
      String value;
      
      // the response should include the following headers
      Vector headerVector=new Vector(); // workaround for introspection problems
      Hashtable expectHeaders=new Hashtable();
  
      public HeaderMatch() {
      }
  
      // -------------------- 
  
      public void setName( String n ) {
  	name=n;
      }
  
      public void setValue( String v ) {
  	value=v;
      }
  
      // Multiple headers ?
      public void addHeader( Header rh ) {
  	headerVector.addElement( rh );
      }
  
      /** Verify that response includes the expected headers.
       *  The value is a "|" separated list of headers to expect.
       *  ?? Do we need that ?
       */
      public void setExpectHeaders( String s ) {
         Header.parseHeadersAsString( s, headerVector );
      }
  
      public Hashtable getExpectHeaders() {
  	if( name!=null ) {
  	    headerVector.addElement( new Header( name, value ));
  	}
  	if( headerVector.size() > 0 ) {
  	    Enumeration en=headerVector.elements();
  	    while( en.hasMoreElements()) {
  		Header rh=(Header)en.nextElement();
  		expectHeaders.put( rh.getName(), rh );
  	    }
  	    headerVector=new Vector();
  	}
  	return expectHeaders;
      }
      
      public String getTestDescription() {
  	StringBuffer desc=new StringBuffer();
  	boolean needAND=false;
  	
  	if( getExpectHeaders().size() > 0 ) {
  	    Enumeration e=expectHeaders.keys();
  	    while( e.hasMoreElements()) {
  		if( needAND ) desc.append( " && " );
  		needAND=true;
  		String key=(String)e.nextElement();
  		Header h=(Header)expectHeaders.get(key);
  		desc.append("( responseHeader '" + h.getName() +
  			    ": " + h.getValue() + "' ) ");
  	    }
  	}
  
  	desc.append( " == " ).append( magnitude );
  	return desc.toString();
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() {
  	try {
  	    result=checkResponse( magnitude );
  	} catch(Exception ex ) {
  	    ex.printStackTrace();
  	    result=false;
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
  	String responseLine=response.getResponseLine();
  	Hashtable headers=response.getHeaders();
  	
          boolean responseStatus = true;
  	
  	getExpectHeaders();
  	if( expectHeaders.size() > 0 ) {
  	    // Check if we got the expected headers
  	    if(headers==null) {
  		log("ERROR no response header, expecting header");
  	    }
  	    Enumeration e=expectHeaders.keys();
  	    while( e.hasMoreElements()) {
  		String key=(String)e.nextElement();
  		Header expH=(Header)expectHeaders.get(key);
  		String value=expH.getValue();
  		Header resH=(Header)headers.get(key);
  		String respValue=(resH==null)? "": resH.getValue();
  		if( respValue==null || respValue.indexOf( value ) <0 ) {
  		    log("ERROR expecting header " + key + ":" +
  			value + " \nGOT: " + respValue+ " HEADERS(" +
  			Header.toString(headers) + ")");
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	return responseStatus;
      }
      
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/matchers/HttpStatusMatch.java
  
  Index: HttpStatusMatch.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test.matchers;
  
  import org.apache.tomcat.util.test.*;
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  
  /**
   *  Test if the HTTP response has a certain status code 
   */
  public class HttpStatusMatch extends Matcher {
  
      // Match request line
      String returnCode=null;
  
      public HttpStatusMatch() {
      }
  
      // -------------------- 
      
      /** Verify the response code
       */
      public void setMatch( String s ) {
  	this.returnCode=s;
      }
  
      public void setReturnCode( String s ) {
  	this.returnCode=s;
      }
  
      /** A test description of the test beeing made
       */
      public String getTestDescription() {
  	StringBuffer desc=new StringBuffer();
  	if( returnCode != null ) {
  	    desc.append("( returnCode matches '" + returnCode + "') ");
  	}
  	desc.append( " == " ).append( magnitude );
  	return desc.toString();
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() {
  	try {
  	    result=checkResponse( magnitude );
  	} catch(Exception ex ) {
  	    ex.printStackTrace();
  	    result=false;
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
  	String responseLine=response.getResponseLine();
  	Hashtable headers=response.getHeaders();
  	
          boolean responseStatus = true;
  	
  	// you can't check return code on http 0.9
  	if( returnCode != null ) {
  	    boolean match= ( responseLine!=null &&
  			     responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  		responseStatus = false;
  		log("    Expecting: " + returnCode );
  		log("    Got      : " + responseLine);
  	    }
  	}
  
  	return responseStatus;
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/matchers/ResponseMatch.java
  
  Index: ResponseMatch.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test.matchers;
  
  import org.apache.tomcat.util.test.*;
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  /**
     Check if the response contains a substring
  */
  public class ResponseMatch extends Matcher {
      // Match the body against a string
      String responseMatch;
  
      public ResponseMatch() {
      }
  
      // -------------------- 
  
      /** Verify that response match the string
       */
      public void setMatch( String s ) {
  	this.responseMatch=s;
      }
  
      /** Verify that response match the string
       */
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      /** A test description of the test beeing made
       */
      public String getTestDescription() {
  	StringBuffer desc=new StringBuffer();
  
  	desc.append("( responseBody matches '"+ responseMatch + "') ");
  	return desc.toString();
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() {
  	try {
  	    result=checkResponse( magnitude );
  	} catch(Exception ex ) {
  	    ex.printStackTrace();
  	    result=false;
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
  	String responseLine=response.getResponseLine();
  	Hashtable headers=response.getHeaders();
  	
          boolean responseStatus = true;
  	
  	String responseBody=response.getResponseBody();
  	    
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		log("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    boolean match=responseBody.indexOf( responseMatch ) >= 0; 
  	    if( match != testCondition ) {
  		responseStatus = false;
  		log("ERROR: expecting match on " + responseMatch);
  		log("GOT: " );
  		log(responseBody );
  	    }
  	}
  
  	
  	return responseStatus;
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/util/test/matchers/ResponseMatchFile.java
  
  Index: ResponseMatchFile.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.util.test.matchers;
  
  import org.apache.tomcat.util.test.*;
  import java.net.*;
  import java.io.*;
  import java.util.*;
  import java.net.*;
  
  /**
     Check if the response matches a response file
  */
  public class ResponseMatchFile extends Matcher {
      // Match the body against a list of strings in a file
      String responseMatchFile;
  
      public ResponseMatchFile() {
      }
  
      // -------------------- 
  
      /** Verify that response matches a list of strings in a file
       */
      public void setFile( String s ) {
  	this.responseMatchFile=s;
      }
      public void setResponseMatchFile( String s ) {
  	this.responseMatchFile=s;
      }
  
      /** A test description of the test beeing made
       */
      public String getTestDescription() {
  	StringBuffer desc=new StringBuffer();
  	boolean needAND=false;
  
  	// if match file is specified
  	if( responseMatchFile != null ) {
  	    if( needAND ) desc.append( " && " );
  	    needAND=true;
  
  	    desc.append("( responseBody matches lines in '"+
  			responseMatchFile + "') ");
          }
  
  	desc.append( " == " ).append( magnitude );
  	return desc.toString();
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() {
  	try {
  	    result=checkResponse( magnitude );
  	} catch(Exception ex ) {
  	    ex.printStackTrace();
  	    result=false;
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
  	String responseLine=response.getResponseLine();
  	Hashtable headers=response.getHeaders();
  	
          boolean responseStatus = true;
  	
  	String responseBody=response.getResponseBody();
  	    
  	// if match file is specified
  	if( responseMatchFile != null ) {
  	    try {
  		boolean desiredResult = true;
  		FileReader fr=new FileReader( responseMatchFile);
  		BufferedReader br = new BufferedReader( fr );
  
  		String expected = br.readLine();
  		while (expected != null) {
  		    if ( "!=".equals(expected) )
  			desiredResult = false;
  		    else {
  			boolean result = responseBody.indexOf( expected ) >= 0;
  			if( result != desiredResult ) {
  			    responseStatus = false;
  			    if ( desiredResult )
  				log("ERROR: expecting match on " + expected);
  			    else
  				log("ERROR: expecting no match on " + expected);
  			    log("In match file: " + responseMatchFile);
  			    log("====================Got:");
  			    log(responseBody );
  			    log("====================");
  			}
  		    }
  		    expected = br.readLine();
  		}
  		br.close();
  	    } catch (FileNotFoundException ex) {
          	log("\tMatch file not found: " + responseMatchFile);
  		log("====================Got:");
  		log(responseBody );
  		log("====================");
  		responseStatus = false;
  	    } catch ( IOException ex ) {
          	log("\tError reading match file: " + responseMatchFile);
          	log(ex.toString());
  		responseStatus = false;
  	    }
  	}
  	
  	return responseStatus;
      }
  }
  
  
  

Mime
View raw message