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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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 [EMAIL PROTECTED] * * 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; } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]