craigmcc 01/04/16 21:22:26 Modified: tester/src/bin tester.xml tester/src/tester/org/apache/tester TestClient.java tester/web/WEB-INF web.xml Added: tester/src/tester/org/apache/tester Golden01.java tester/web/golden Golden01.txt Log: Add golden file support to the unit tester for Tomcat 4.0. This is very useful in testing JSP pages, where you want to look at the entire output of the response instead of just the first line. To create a test with a golden file: * Add the golden file itself to directory "tester/web/golden/". * Add the test(s) to "tester/src/bin/tester.xml" as usual, with the "golden" attribute specifying the server-relative path to the golden file (which is retrieved from the server via HTTP). Typically, you will specify the "golden" attribute with a path that is relative to the "golden.path" property, which defaults to "${context.path}/golden". The ROOT target includes a simple test to ensure that the golden file processing mechanism works correctly. Revision Changes Path 1.29 +11 -0 jakarta-tomcat-4.0/tester/src/bin/tester.xml Index: tester.xml =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/bin/tester.xml,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- tester.xml 2001/04/14 00:03:17 1.28 +++ tester.xml 2001/04/17 04:22:24 1.29 @@ -8,6 +8,7 @@ <!-- <property name="protocol" value="HTTP/1.0"/> --> <property name="protocol" value=""/> <!-- Use HttpURLConnection --> <property name="context.path" value="/tester"/> + <property name="golden.path" value="${context.path}/golden"/> <property name="manager.path" value="/manager"/> <taskdef name="tester" classname="org.apache.tester.TestClient"/> @@ -33,6 +34,16 @@ <tester host="${host}" port="${port}" protocol="${protocol}" request="/examples/../.." debug="${debug}" status="404"/> + + <!-- Should be able to successfully retrieve a golden file --> + <tester host="${host}" port="${port}" protocol="${protocol}" + request="${context.path}/Golden01" + golden="${golden.path}/Golden01.txt"/> + + <!-- Should be able to successfully retrieve a golden file --> + <tester host="${host}" port="${port}" protocol="${protocol}" + request="${context.path}/WrappedGolden01" + golden="${golden.path}/Golden01.txt"/> </target> 1.7 +147 -31 jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/TestClient.java Index: TestClient.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/TestClient.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- TestClient.java 2001/02/04 04:49:38 1.6 +++ TestClient.java 2001/04/17 04:22:25 1.7 @@ -86,6 +86,8 @@ * </pre> * and accepts the following configuration properties:</p> * <ul> + * <li><strong>golden</strong> - The server-relative path of the static + * resource containing the golden file for this request.</li> * <li><strong>host</strong> - The server name to which this request will be * sent. Defaults to <code>localhost</code> if not specified.</li> * <li><strong>inContent</strong> - The data content that will be submitted @@ -115,7 +117,7 @@ * </ul> * * @author Craig R. McClanahan - * @version $Revision: 1.6 $ $Date: 2001/02/04 04:49:38 $ + * @version $Revision: 1.7 $ $Date: 2001/04/17 04:22:25 $ */ public class TestClient extends Task { @@ -125,6 +127,13 @@ /** + * The saved golden file we will compare to the response. Each element + * contains a line of text without any line delimiters. + */ + protected ArrayList saveGolden = new ArrayList(); + + + /** * The saved headers we received in our response. The key is the header * name (converted to lower case), and the value is an ArrayList of the * string value(s) received for that header. @@ -132,6 +141,13 @@ protected HashMap saveHeaders = new HashMap(); + /** + * The response file to be compared to the golden file. Each element + * contains a line of text without any line delimiters. + */ + protected ArrayList saveResponse = new ArrayList(); + + // ------------------------------------------------------------- Properties @@ -150,6 +166,20 @@ /** + * The server-relative request URI of the golden file for this request. + */ + protected String golden = null; + + public String getGolden() { + return (this.golden); + } + + public void setGolden(String golden) { + this.golden = golden; + } + + + /** * The host name to which we will connect. */ protected String host = "localhost"; @@ -345,6 +375,12 @@ public void execute() throws BuildException { saveHeaders.clear(); + try { + readGolden(); + } catch (IOException e) { + System.out.println("FAIL: readGolden(" + golden + ")"); + e.printStackTrace(System.out); + } if ((protocol == null) || (protocol.length() == 0)) executeHttp(); else @@ -440,21 +476,19 @@ String outText = ""; boolean eol = false; InputStream is = conn.getInputStream(); - if (is != null) { - while (true) { - int b = is.read(); - if (b < 0) - break; - char ch = (char) b; - if ((ch == '\r') || (ch == '\n')) - eol = true; - if (!eol) - outData += ch; - else - outText += ch; - } - is.close(); + int lines = 0; + while (true) { + String line = read(is); + if (line == null) + break; + if (lines == 0) + outData = line; + else + outText += line + "\r\n"; + saveResponse.add(line); + lines++; } + is.close(); // Dump out the response stuff if (debug >= 1) @@ -489,12 +523,17 @@ success = false; } if (success) { + result = validateHeaders(); + if (result != null) + success = false; + } + if (success) { result = validateData(outData); if (result != null) success = false; } if (success) { - result = validateHeaders(); + result = validateGolden(); if (result != null) success = false; } @@ -676,21 +715,19 @@ // Acquire the response data (if any) String outData = ""; String outText = ""; - boolean eol = false; - if (is != null) { - while (true) { - int b = is.read(); - if (b < 0) - break; - char ch = (char) b; - if ((ch == '\r') || (ch == '\n')) - eol = true; - if (!eol) - outData += ch; - else - outText += ch; - } + int lines = 0; + while (true) { + line = read(is); + if (line == null) + break; + if (lines == 0) + outData = line; + else + outText += line + "\r\n"; + saveResponse.add(line); + lines++; } + is.close(); if (debug >= 1) { System.out.println("DATA: " + outData); if (outText.length() > 2) @@ -709,12 +746,17 @@ success = false; } if (success) { + result = validateHeaders(); + if (result != null) + success = false; + } + if (success) { result = validateData(outData); if (result != null) success = false; } if (success) { - result = validateHeaders(); + result = validateGolden(); if (result != null) success = false; } @@ -824,6 +866,44 @@ /** + * Read and save the contents of the golden file for this test, if any. + * Otherwise, the <code>saveGolden</code> list will be empty. + * + * @exception IOException if an input/output error occurs + */ + protected void readGolden() throws IOException { + + // Was a golden file specified? + saveGolden.clear(); + if (golden == null) + return; + + // Create a connection to receive the golden file contents + URL url = new URL("http", host, port, golden); + HttpURLConnection conn = + (HttpURLConnection) url.openConnection(); + conn.setAllowUserInteraction(false); + conn.setDoInput(true); + conn.setDoOutput(false); + conn.setFollowRedirects(true); + conn.setRequestMethod("GET"); + + // Connect to the server and retrieve the golden file + conn.connect(); + InputStream is = conn.getInputStream(); + while (true) { + String line = read(is); + if (line == null) + break; + saveGolden.add(line); + } + is.close(); + conn.disconnect(); + + } + + + /** * Save the specified header name and value in our collection. * * @param name Header name to save @@ -857,6 +937,42 @@ else return ("Expected data '" + outContent + "', got data '" + data + "'"); + + } + + + /** + * Validate the response against the golden file (if any). Return + * <code>null</code> for no problems, or an error message. + */ + protected String validateGolden() { + + if (golden == null) + return (null); + boolean ok = true; + if (saveGolden.size() != saveResponse.size()) + ok = false; + if (ok) { + for (int i = 0; i < saveGolden.size(); i++) { + String golden = (String) saveGolden.get(i); + String response = (String) saveResponse.get(i); + if (!golden.equals(response)) { + ok = false; + break; + } + } + } + if (ok) + return (null); + System.out.println("EXPECTED: ======================================"); + for (int i = 0; i < saveGolden.size(); i++) + System.out.println((String) saveGolden.get(i)); + System.out.println("================================================"); + System.out.println("RECEIVED: ======================================"); + for (int i = 0; i < saveResponse.size(); i++) + System.out.println((String) saveResponse.get(i)); + System.out.println("================================================"); + return ("Failed Golden File Comparison"); } 1.1 jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/Golden01.java Index: Golden01.java =================================================================== /* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999, 2000, 2001 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * 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 Software Foundation. * * * * 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 indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= */ package org.apache.tester; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** * Simple test for the golden file mechanism. This test generates a response * with known contents for comparison to the golden file. * * @author Craig R. McClanahan * @version $Revision: 1.1 $ $Date: 2001/04/17 04:22:25 $ */ public class Golden01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/plain"); PrintWriter writer = response.getWriter(); writer.println("This is the"); writer.println("first golden file"); writer.println("to be tested."); } } 1.21 +20 -0 jakarta-tomcat-4.0/tester/web/WEB-INF/web.xml Index: web.xml =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/tester/web/WEB-INF/web.xml,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- web.xml 2001/04/14 00:03:17 1.20 +++ web.xml 2001/04/17 04:22:25 1.21 @@ -117,6 +117,11 @@ <filter-mapping> <filter-name>HttpFilter</filter-name> + <url-pattern>/WrappedGolden01</url-pattern> + </filter-mapping> + + <filter-mapping> + <filter-name>HttpFilter</filter-name> <url-pattern>/WrappedInclude01</url-pattern> </filter-mapping> @@ -308,6 +313,11 @@ </servlet> <servlet> + <servlet-name>Golden01</servlet-name> + <servlet-class>org.apache.tester.Golden01</servlet-class> + </servlet> + + <servlet> <servlet-name>Include01</servlet-name> <servlet-class>org.apache.tester.Include01</servlet-class> </servlet> @@ -579,6 +589,16 @@ <servlet-mapping> <servlet-name>GetQueryString01</servlet-name> <url-pattern>/WrappedGetQueryString01</url-pattern> + </servlet-mapping> + + <servlet-mapping> + <servlet-name>Golden01</servlet-name> + <url-pattern>/Golden01</url-pattern> + </servlet-mapping> + + <servlet-mapping> + <servlet-name>Golden01</servlet-name> + <url-pattern>/WrappedGolden01</url-pattern> </servlet-mapping> <servlet-mapping> 1.1 jakarta-tomcat-4.0/tester/web/golden/Golden01.txt Index: Golden01.txt =================================================================== This is the first golden file to be tested.