You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2001/01/20 03:35:36 UTC

cvs commit: jakarta-tomcat/src/tests/share/gtest GTest.java

costin      01/01/19 18:35:36

  Added:       src/tests/share/gtest GTest.java
  Log:
  Added missing file, needed to run the self-test ( was moved from share/
  since was not a required part of tomcat, and is used only in the test
  app ).
  
  There are many enhancements needed to make it really easy to run the
  tests. I guess we'll do them as we go.
  
  I also did a small change - GTest new extends Task and uses log() instead
  of System.out(). ( I'll check in a jsp file that runs the test - the change is
  needed to send the output to the right destination ).
  
  Note: this is a change to the CVS HEAD. IMHO there is nothing to stop
  fixes to go in - as long as we don't call it anyway. I'll commit a number
  of fixes over the weekend - including restoring the JDK1.1 build ( plus
  a solution that will simplify supporting JDK1.1 ), and I'll probably finish
  the .jsp taglib that runs the tests. Lazy consensus should work as before -
  if anyone has a problem with any checkin, please -1 it.
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat/src/tests/share/gtest/GTest.java
  
  Index: GTest.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.tools.ant.Task;
  import org.apache.tools.ant.BuildException;
  
  
  /** Test a web application. Will send a http request and
      verify the response code, compare the response with a golden
      file or find strings.
  */
  public class GTest extends Task {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;
  
      String description="No description";
  
      String request;
      Hashtable requestHeaders;
      String content;
      
      // Expected response
      boolean magnitude=true;
      boolean exactMatch=false;
      // Match the body against a golden file
      String goldenFile;
      // Match the body against a string
      String responseMatch;
      // the response should include the following headers
      Hashtable expectHeaders;
      // Match request line
      String returnCode="";
  
      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;
  
      public GTest() {
      }
      
      /** Set the base URL ( server + webapp path )
       */
      public void setPrefix(String prefix) {
  	this.prefix=prefix;
      }
      
      public void setHost(String h) {
  	this.host=h;
      }
      
      public void setPort(String portS) {
  	this.port=Integer.valueOf( portS).intValue();
      }
  
      public void setExactMatch(String exact) {
  	exactMatch=Boolean.valueOf( exact ).booleanValue();
      }
  
      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  	this.port=i;
      }
  
      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  	return description;
      }
  
      public void setDescription(String description) {
  	this.description=description;
      }
  
      /** Do a POST with the specified content
       */
      public void setContent(String s) {
  	this.content=s;
      }
  
      /** Display debug info
       */
      public void setDebug( String debugS ) {
  	debug=Integer.valueOf( debugS).intValue();
      }
  
      /** True if this is a positive test, false for negative
       */
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();   
      }
  
      /** Compare with the golden file
       */
      public void setGoldenFile( String s ) {
  	this.goldenFile=s;
      }
  
      /** Verify that response includes the expected headers
       */
      public void setExpectHeaders( String s ) {
  	this.expectHeaders=new Hashtable();
  	parseHeader( s, expectHeaders );
      }
  
      /** Verify that response match the string
       */
      public void setResponseMatch( String s ) {
  	this.responseMatch=s;
      }
  
      /** Request line ( will have the host and context path prefix)
       */
      public void setRequest( String s ) {
  	this.request=s;
      }
      
      /** Verify the response code
       */
      public void setReturnCode( String s ) {
  	this.returnCode=s;
      }
  
      /** Send additional headers
       */
      public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }
  
      // -------------------- Execute the request --------------------
  
      public void execute() throws BuildException {
  	
  	try {
  	    dispatch(request, null);
  
  	    boolean result=checkResponse( magnitude );
  	    if(result) {
  		if(  "No description".equals( description )) {
  		    log("OK " + request );
  		}
  		else
  		    log("OK " + description + " (" + request + ")");
  	    } else {
  		if(  "No description".equals( description )) {
  		    log("FAIL " + request );
  		} else
  		    log("FAIL " + description + " (" + request + ")" );
  	    }
  	} catch(Exception ex ) {
  	    if(  "No description".equals( description )) {
  		log("FAIL " + request );
  	    } else
  		log("FAIL " + description + " (" + request + ")" );
  	    ex.printStackTrace();
  	}
      }
  
      private boolean checkResponse(boolean testCondition)
  	throws Exception
      {
          boolean responseStatus = true;
  	
  	// If returnCode doesn't match
  	if( request.indexOf( "HTTP/1." ) > -1) {
  	    boolean match= ( responseLine!=null && responseLine.indexOf(returnCode) > -1);
  	    if( match != testCondition ) {
  		responseStatus = false;
  		log("ERROR in: " + request);
  		log("    Expecting: " + returnCode );
  		log("    Got      : " + responseLine);
  	    }
  	}
  
  	if( expectHeaders != null ) {
  	    // 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();
  		String value=(String)expectHeaders.get(key);
  		String respValue=(String)headers.get(key);
  		if( respValue==null || respValue.indexOf( value ) <0 ) {
  		    log("ERROR expecting header " + key + ":" +
  				       value + " GOT: " + respValue+ " HEADERS(" + headers + ")");
  		    
  		    return false;
  		}
  	    }
  
  	}
  	
  	if( responseMatch != null ) {
  	    // check if we got the string we wanted
  	    if( responseBody == null ) {
  		log("ERROR: got no response, expecting " + responseMatch);
  		return false;
  	    }
  	    if( responseBody.indexOf( responseMatch ) < 0) {
  		responseStatus = false;
  		log("ERROR: expecting match on " + responseMatch);
  		log("GOT: " );
  		log(responseBody );
  	    }
  	}
  
  	// 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 + ")in : " + request);
  	    log("====================Expecting: ");
  	    log(expResult.toString());
  	    log("====================Got:");
  	    log(responseBody);
  	    log("====================");
  	}	    
  	
  	return responseStatus;
      }
      
      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  	throws Exception
      {
  	// XXX headers are ignored
  	Socket s = null;
  
  	s = new Socket( host, port);
  	InputStream is=	s.getInputStream();
  
  	// Write the request
  	s.setSoLinger( true, 1000);
  	OutputStream os=s.getOutputStream();
  	OutputStreamWriter out=new OutputStreamWriter(os);
  	PrintWriter pw = new PrintWriter(out);
  
  	try {
  	    pw.println(request);
  	    
  	    if( content != null) {
  		pw.println("Content-Length: " + content.length());
  	    }
  	    
  	    if( request.indexOf( "HTTP/1." ) > -1) 
  		pw.println("");
  	    
  	    if( content != null) {
  		pw.print(content);
  		// XXX no /n at the end -see HTTP specs!
  	    }
  	    
  	    pw.flush();
  	} catch (Exception ex1 ) {
  	    log("Error writing request " + ex1);
  	}
  	
  	try {
  	    // http 0.9
  	    if( request.indexOf( "HTTP/1." ) > -1) {
  		responseLine = read( is );
  		
  		if( debug>0) log("RESPONSE: " + responseLine );
  		headers=parseHeaders( is );
  	    }
  
  	    // else do content matching as well
  	    StringBuffer result =  readBody( is );
  	    if(result!=null)
  		responseBody=result.toString();
  
  	    if(debug>0) log("BODY: " + responseBody );
  	} catch( SocketException ex ) {
  	    log("Socket Exception: " + ex);
  	    ex.printStackTrace();
  	    s.close();
  	    return;
  	}
  	s.close();
      }
  
      // Parse a file into a String.
      private StringBuffer getExpectedResult()
  	throws IOException
      {
          StringBuffer expResult = new StringBuffer("NONE");
  
          try {
  	    //	    InputStream in = this.getClass().getResourceAsStream(goldenFile);
  	    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;
      }
  
      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  	Hashtable headers=new Hashtable();
  	while (true) {
  	    // Read the next header line
  	    String line = read(is);
  	    if ((line == null) || (line.length() < 1)) {
  		break;
  	    }
  
  	    parseHeader( line, headers);
  	    if( debug>0) log("HEADER: " +line +"X" );
  
  	}
  
  	return headers;
      }
  
      private void parseHeader(String line, Hashtable headers) {
  	// Parse the header name and value
  	int colon = line.indexOf(":");
  	if (colon < 0) {
  	    log("ERROR: Wrong Header Line: " +  line );
  	    return;
  	}
  	String name = line.substring(0, colon).trim();
  	String value = line.substring(colon + 1).trim();
  
  	//	log("HEADER: " +name + " " + value);
  	headers.put(name, value);
      }
  
      /**
       * Read a line from the specified servlet input stream, and strip off
       * the trailing carriage return and newline (if any).  Return the remaining
       * characters that were read as a string.
       *
       * @returns The line that was read, or <code>null</code> if end of file
       *  was encountered
       *
       * @exception IOException if an input/output error occurred
       */
      private String read(InputStream input) throws IOException {
  	// Read the next line from the input stream
  	StringBuffer sb = new StringBuffer();
  	while (true) {
  	    try {
  		int ch = input.read();
  		//		log("XXX " + (char)ch );
  		if (ch < 0) {
  		    if (sb.length() == 0) {
  			if(debug>0) log("Error reading line " + ch + " " + sb.toString() );
  			return "";
  		    } else {
  			break;
  		    }
  		} else if (ch == '\n') {
  		    break;
  		}
  		sb.append((char) ch);
  	    } catch( IOException ex ) {
  		log("Error reading : " + ex );
  		debug=1;
  		if(debug>0) log("Partial read: " + sb.toString());
  		ex.printStackTrace();
  		//break;
  	    }
  	}
  
  	// Strip any trailing carriage return
  	int n = sb.length();
  	if ((n > 0) && (sb.charAt(n - 1) == '\r')) {
  	    sb.setLength(n - 1);
  	}
  
  	// Convert the line to a String and return it
  	return (sb.toString());
      }
  
  }
  
  
  

Tomcat bug - corrupt library

Posted by Filip Hanik <fi...@filip.net>.
Hi,
if you add in a corrupt library to WEB-INF/lib/
then tomcat will not process the remining of the libraries (jar, zip files)
and will start up without notifying you,
later when you try to load a class that was in a library that didn't get
loaded you get a null pointer.
I had a hard time tracking this down, but finally figured out that one of
our jar files got corrupt during the FTP transfer and that resulted in the a
lot of jar files didn't get loaded.
I would strongly recommend that Tomcat throws an exception if it can not
load a jar file, or at least give some warning.
let me know if you want specific examples, or more explanation
Filip

~
Namaste - I bow to the divine in you.
~
Filip Hanik
Technical Architect
filip@filip.net

----- Original Message -----
From: <co...@apache.org>
To: <ja...@apache.org>
Sent: Friday, January 19, 2001 6:35 PM
Subject: cvs commit: jakarta-tomcat/src/tests/share/gtest GTest.java


costin      01/01/19 18:35:36

  Added:       src/tests/share/gtest GTest.java
  Log:
  Added missing file, needed to run the self-test ( was moved from share/
  since was not a required part of tomcat, and is used only in the test
  app ).

  There are many enhancements needed to make it really easy to run the
  tests. I guess we'll do them as we go.

  I also did a small change - GTest new extends Task and uses log() instead
  of System.out(). ( I'll check in a jsp file that runs the test - the
change is
  needed to send the output to the right destination ).

  Note: this is a change to the CVS HEAD. IMHO there is nothing to stop
  fixes to go in - as long as we don't call it anyway. I'll commit a number
  of fixes over the weekend - including restoring the JDK1.1 build ( plus
  a solution that will simplify supporting JDK1.1 ), and I'll probably
finish
  the .jsp taglib that runs the tests. Lazy consensus should work as
before -
  if anyone has a problem with any checkin, please -1 it.

  Revision  Changes    Path
  1.1                  jakarta-tomcat/src/tests/share/gtest/GTest.java

  Index: GTest.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.tools.ant.Task;
  import org.apache.tools.ant.BuildException;


  /** Test a web application. Will send a http request and
      verify the response code, compare the response with a golden
      file or find strings.
  */
  public class GTest extends Task {
      String prefix="http://localhost:8080/test";
      String host="localhost";
      int port=8080;
      int debug=0;

      String description="No description";

      String request;
      Hashtable requestHeaders;
      String content;

      // Expected response
      boolean magnitude=true;
      boolean exactMatch=false;
      // Match the body against a golden file
      String goldenFile;
      // Match the body against a string
      String responseMatch;
      // the response should include the following headers
      Hashtable expectHeaders;
      // Match request line
      String returnCode="";

      // Actual response
      String responseLine;
      String responseBody;
      Hashtable headers;

      public GTest() {
      }

      /** Set the base URL ( server + webapp path )
       */
      public void setPrefix(String prefix) {
  this.prefix=prefix;
      }

      public void setHost(String h) {
  this.host=h;
      }

      public void setPort(String portS) {
  this.port=Integer.valueOf( portS).intValue();
      }

      public void setExactMatch(String exact) {
  exactMatch=Boolean.valueOf( exact ).booleanValue();
      }

      /** Set the port as int - different name to avoid confusing ant
       */
      public void setPortInt(int i) {
  this.port=i;
      }

      /** Description should be in <test description=""/>
       */
      public String getDescription() {
  return description;
      }

      public void setDescription(String description) {
  this.description=description;
      }

      /** Do a POST with the specified content
       */
      public void setContent(String s) {
  this.content=s;
      }

      /** Display debug info
       */
      public void setDebug( String debugS ) {
  debug=Integer.valueOf( debugS).intValue();
      }

      /** True if this is a positive test, false for negative
       */
      public void setMagnitude( String magnitudeS ) {
          magnitude = Boolean.valueOf(magnitudeS).booleanValue();
      }

      /** Compare with the golden file
       */
      public void setGoldenFile( String s ) {
  this.goldenFile=s;
      }

      /** Verify that response includes the expected headers
       */
      public void setExpectHeaders( String s ) {
  this.expectHeaders=new Hashtable();
  parseHeader( s, expectHeaders );
      }

      /** Verify that response match the string
       */
      public void setResponseMatch( String s ) {
  this.responseMatch=s;
      }

      /** Request line ( will have the host and context path prefix)
       */
      public void setRequest( String s ) {
  this.request=s;
      }

      /** Verify the response code
       */
      public void setReturnCode( String s ) {
  this.returnCode=s;
      }

      /** Send additional headers
       */
      public void setHeaders( String s ) {
         requestHeaders=new Hashtable();
         parseHeader( s, requestHeaders );
      }

      // -------------------- Execute the request --------------------

      public void execute() throws BuildException {

  try {
      dispatch(request, null);

      boolean result=checkResponse( magnitude );
      if(result) {
  if(  "No description".equals( description )) {
      log("OK " + request );
  }
  else
      log("OK " + description + " (" + request + ")");
      } else {
  if(  "No description".equals( description )) {
      log("FAIL " + request );
  } else
      log("FAIL " + description + " (" + request + ")" );
      }
  } catch(Exception ex ) {
      if(  "No description".equals( description )) {
  log("FAIL " + request );
      } else
  log("FAIL " + description + " (" + request + ")" );
      ex.printStackTrace();
  }
      }

      private boolean checkResponse(boolean testCondition)
  throws Exception
      {
          boolean responseStatus = true;

  // If returnCode doesn't match
  if( request.indexOf( "HTTP/1." ) > -1) {
      boolean match= ( responseLine!=null &&
responseLine.indexOf(returnCode) > -1);
      if( match != testCondition ) {
  responseStatus = false;
  log("ERROR in: " + request);
  log("    Expecting: " + returnCode );
  log("    Got      : " + responseLine);
      }
  }

  if( expectHeaders != null ) {
      // 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();
  String value=(String)expectHeaders.get(key);
  String respValue=(String)headers.get(key);
  if( respValue==null || respValue.indexOf( value ) <0 ) {
      log("ERROR expecting header " + key + ":" +
         value + " GOT: " + respValue+ " HEADERS(" + headers + ")");

      return false;
  }
      }

  }

  if( responseMatch != null ) {
      // check if we got the string we wanted
      if( responseBody == null ) {
  log("ERROR: got no response, expecting " + responseMatch);
  return false;
      }
      if( responseBody.indexOf( responseMatch ) < 0) {
  responseStatus = false;
  log("ERROR: expecting match on " + responseMatch);
  log("GOT: " );
  log(responseBody );
      }
  }

  // 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 + ")in : " + request);
      log("====================Expecting: ");
      log(expResult.toString());
      log("====================Got:");
      log(responseBody);
      log("====================");
  }

  return responseStatus;
      }

      /** Invoke a request, set headers, responseLine, body
       */
      private void dispatch(String request, Hashtable requestHeaders)
  throws Exception
      {
  // XXX headers are ignored
  Socket s = null;

  s = new Socket( host, port);
  InputStream is= s.getInputStream();

  // Write the request
  s.setSoLinger( true, 1000);
  OutputStream os=s.getOutputStream();
  OutputStreamWriter out=new OutputStreamWriter(os);
  PrintWriter pw = new PrintWriter(out);

  try {
      pw.println(request);

      if( content != null) {
  pw.println("Content-Length: " + content.length());
      }

      if( request.indexOf( "HTTP/1." ) > -1)
  pw.println("");

      if( content != null) {
  pw.print(content);
  // XXX no /n at the end -see HTTP specs!
      }

      pw.flush();
  } catch (Exception ex1 ) {
      log("Error writing request " + ex1);
  }

  try {
      // http 0.9
      if( request.indexOf( "HTTP/1." ) > -1) {
  responseLine = read( is );

  if( debug>0) log("RESPONSE: " + responseLine );
  headers=parseHeaders( is );
      }

      // else do content matching as well
      StringBuffer result =  readBody( is );
      if(result!=null)
  responseBody=result.toString();

      if(debug>0) log("BODY: " + responseBody );
  } catch( SocketException ex ) {
      log("Socket Exception: " + ex);
      ex.printStackTrace();
      s.close();
      return;
  }
  s.close();
      }

      // Parse a file into a String.
      private StringBuffer getExpectedResult()
  throws IOException
      {
          StringBuffer expResult = new StringBuffer("NONE");

          try {
      //     InputStream in =
this.getClass().getResourceAsStream(goldenFile);
      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;
      }

      // ==================== Code from JSERV !!! ====================
      /**
       * Parse the incoming HTTP request headers, and set the corresponding
       * request properties.
       *
       *
       * @exception IOException if an input/output error occurs
       */
      private Hashtable parseHeaders(InputStream is) throws IOException {
  Hashtable headers=new Hashtable();
  while (true) {
      // Read the next header line
      String line = read(is);
      if ((line == null) || (line.length() < 1)) {
  break;
      }

      parseHeader( line, headers);
      if( debug>0) log("HEADER: " +line +"X" );

  }

  return headers;
      }

      private void parseHeader(String line, Hashtable headers) {
  // Parse the header name and value
  int colon = line.indexOf(":");
  if (colon < 0) {
      log("ERROR: Wrong Header Line: " +  line );
      return;
  }
  String name = line.substring(0, colon).trim();
  String value = line.substring(colon + 1).trim();

  // log("HEADER: " +name + " " + value);
  headers.put(name, value);
      }

      /**
       * Read a line from the specified servlet input stream, and strip off
       * the trailing carriage return and newline (if any).  Return the
remaining
       * characters that were read as a string.
       *
       * @returns The line that was read, or <code>null</code> if end of
file
       *  was encountered
       *
       * @exception IOException if an input/output error occurred
       */
      private String read(InputStream input) throws IOException {
  // Read the next line from the input stream
  StringBuffer sb = new StringBuffer();
  while (true) {
      try {
  int ch = input.read();
  // log("XXX " + (char)ch );
  if (ch < 0) {
      if (sb.length() == 0) {
  if(debug>0) log("Error reading line " + ch + " " + sb.toString() );
  return "";
      } else {
  break;
      }
  } else if (ch == '\n') {
      break;
  }
  sb.append((char) ch);
      } catch( IOException ex ) {
  log("Error reading : " + ex );
  debug=1;
  if(debug>0) log("Partial read: " + sb.toString());
  ex.printStackTrace();
  //break;
      }
  }

  // Strip any trailing carriage return
  int n = sb.length();
  if ((n > 0) && (sb.charAt(n - 1) == '\r')) {
      sb.setLength(n - 1);
  }

  // Convert the line to a String and return it
  return (sb.toString());
      }

  }




---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, email: tomcat-dev-help@jakarta.apache.org