Author: kkolinko Date: Wed Jan 27 13:37:09 2016 New Revision: 1727049 URL: http://svn.apache.org/viewvc?rev=1727049&view=rev Log: Add framework for client-server unit tests, porting it from Tomcat 7. Add support for running the tests with Apache Ant.
The tests can be run with ant download ant test See BUILDING.txt for details. This feature was developed on ^/tomcat/tc6.0.x/branches/tomcat6-testing_20160106 branch. Added: tomcat/tc6.0.x/trunk/test/deployment/ tomcat/tc6.0.x/trunk/test/deployment/dirContext/ - copied from r1727037, tomcat/tc7.0.x/trunk/test/deployment/dirContext/ tomcat/tc6.0.x/trunk/test/deployment/dirNoContext/ - copied from r1727037, tomcat/tc7.0.x/trunk/test/deployment/dirNoContext/ tomcat/tc6.0.x/trunk/test/org/apache/catalina/connector/ tomcat/tc6.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java - copied, changed from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java tomcat/tc6.0.x/trunk/test/org/apache/catalina/core/ tomcat/tc6.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java - copied, changed from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java - copied, changed from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/FastNonSecureRandom.java - copied unchanged from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/FastNonSecureRandom.java tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java - copied, changed from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/Tomcat.java - copied, changed from r1727037, tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/Tomcat.java tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java - copied, changed from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java Removed: tomcat/tc6.0.x/trunk/test/build.xml Modified: tomcat/tc6.0.x/trunk/BUILDING.txt tomcat/tc6.0.x/trunk/build.properties.default tomcat/tc6.0.x/trunk/build.xml tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Modified: tomcat/tc6.0.x/trunk/BUILDING.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/BUILDING.txt?rev=1727049&r1=1727048&r2=1727049&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/BUILDING.txt (original) +++ tomcat/tc6.0.x/trunk/BUILDING.txt Wed Jan 27 13:37:09 2016 @@ -172,3 +172,109 @@ For a quick rebuild of only modified cod cd ${tomcat.source} ant -f dist.xml release + +(8) Tests + +(8.1) Running Tomcat tests + +Tomcat 6 includes a small number of junit tests. (A lot more are available +with Tomcat 7 onwards). + +The tests are not run when a release is built. There is separate command to +run them. + +To run the testsuite use the following command: + + cd ${tomcat.source} + ant download + ant test + +It is advisable to redirect output of the above command to a file for later +inspection. + +The JUnit reports generated by the tests will be written to the following +directory: + + output/build/logs + +By default the testsuite is run three times to test 3 different +implementations of Tomcat connectors: BIO, NIO and APR. (If you are not +familiar with Tomcat connectors, see config/http.html in documentation for +details). + +The 3 runs are enabled and disabled individually by the following +properties, which all are "true" by default: + + execute.test.bio=true + execute.test.nio=true + execute.test.apr=true + +The APR connector can be tested only if Tomcat-Native library binaries are +found by the testsuite. The "test.apr.loc" property specifies the directory +where the library binaries are located. + +By default the "test.apr.loc" property specifies the following location: + + output/build/bin/native/ + +If you are on Windows and want to test the APR connector you can put the +tcnative-1.dll file into ${tomcat.source}/bin/native/ and it will be copied +into the above directory when the build runs. + + +(8.2) Running a single test + +It is possible to run a single JUnit test class by adding the "test.entry" +property to the build.properties file. The property specifies the name of +the test class. + +For example: + + test.entry=org.apache.catalina.util.TestServerInfo + +It is possible to further limit such run to a number of selected test +methods by adding "test.entry.methods" property. The property specifies a +comma-separated list of test case methods. + +For example: + + test.entry=org.apache.el.lang.TestELArithmetic + test.entry.methods=testMultiply01,testMultiply02 + + +(8.3) Other configuration options + + 1. It is possible to configure the directory where JUnit reports are + written to. It is configured by "test.reports" property. The default + value is + + output/build/logs + + 2. It is possible to enable generation of access log file when the tests + are run. This is off by default and can be enabled by the following + property: + + test.accesslog=true + + The "access_log.<date>" file will be written to the same directory as + JUnit reports, + + output/build/logs + + 3. The testsuite respects logging configuration as configured by + ${tomcat.source}/conf/logging.properties + + The log files will be written to the temporary directory used by the + tests, + + output/test-tmp/logs + + 4. It is possible to configure formatter used by JUnit reports. + Configuration properties are "junit.formatter.type", + "junit.formatter.extension" and "junit.formatter.usefile". + + For example the following property disables generation of separate report + files: + + junit.formatter.usefile=false + Modified: tomcat/tc6.0.x/trunk/build.properties.default URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/build.properties.default?rev=1727049&r1=1727048&r2=1727049&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/build.properties.default (original) +++ tomcat/tc6.0.x/trunk/build.properties.default Wed Jan 27 13:37:09 2016 @@ -29,6 +29,20 @@ version.build=45 version.patch=0 version.suffix=-dev +# ----- Build control flags ----- +execute.test.bio=true +execute.test.nio=true +# Still requires APR/native library to be present +execute.test.apr=true +# Stop testing if a failure occurs +test.haltonfailure=false +# Activate AccessLog during testing +test.accesslog=false + +# Some platforms (e.g. OSX El Capitan) require IPv4 to be the default for the +# multicast tests to work +java.net.preferIPv4Stack=false + # ----- Default Base Path for Dependent Packages ----- # Please note this path must be absolute, not relative, # as it is referenced with different working directory @@ -159,3 +173,15 @@ commons-daemon.native.src.loc.1=${base-c commons-daemon.native.src.loc.2=${base-commons.loc.2}/daemon/source/commons-daemon-${commons-daemon.version}-native-src.tar.gz commons-daemon.native.win.loc.1=${base-commons.loc.1}/daemon/binaries/windows/commons-daemon-${commons-daemon.version}-bin-windows-signed.zip commons-daemon.native.win.loc.2=${base-commons.loc.2}/daemon/binaries/windows/commons-daemon-${commons-daemon.version}-bin-windows-signed.zip + +# ----- JUnit Unit Test Suite, version 4.11 or later ----- +junit.version=4.11 +junit.home=${base.path}/junit-${junit.version} +junit.jar=${junit.home}/junit-${junit.version}.jar +junit.loc=${base-maven.loc}/junit/junit/${junit.version}/junit-${junit.version}.jar + +# ----- Hamcrest Library, used by JUnit, version 1.3 or later ---- +hamcrest.version=1.3 +hamcrest.home=${base.path}/hamcrest-${hamcrest.version} +hamcrest.jar=${hamcrest.home}/hamcrest-core-${hamcrest.version}.jar +hamcrest.loc=${base-maven.loc}/org/hamcrest/hamcrest-core/${hamcrest.version}/hamcrest-core-${hamcrest.version}.jar Modified: tomcat/tc6.0.x/trunk/build.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/build.xml?rev=1727049&r1=1727048&r2=1727049&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/build.xml (original) +++ tomcat/tc6.0.x/trunk/build.xml Wed Jan 27 13:37:09 2016 @@ -58,6 +58,10 @@ <property name="tomcat.classes" value="${tomcat.output}/classes"/> <property name="tomcat.dist" value="${tomcat.output}/dist"/> <property name="tomcat.manifests" value="${tomcat.output}/manifests"/> + <property name="test.classes" value="${tomcat.output}/testclasses"/> + <property name="test.temp" value="${tomcat.output}/test-tmp"/> + <property name="test.reports" value="${tomcat.build}/logs"/> + <property name="test.apr.loc" value="${tomcat.build}/bin/native"/> <!-- Can't be lower - jsp uses templates --> <property name="compile.source" value="1.5"/> @@ -91,11 +95,22 @@ <available property="tomcat-dbcp.present" file="${tomcat-dbcp.jar}" /> <available property="jdk16.present" classname="javax.sql.StatementEvent" /> + <!-- Tests To Run --> + <property name="test.name" value="**/Test*.java"/> + <property name="test.formatter" value="-Dorg.apache.juli.formatter=java.util.logging.SimpleFormatter"/> + <!-- Classpath --> <path id="tomcat.classpath"> <pathelement location="${ant.jar}"/> <pathelement location="${jdt.jar}"/> </path> + <path id="tomcat.test.classpath"> + <pathelement location="${tomcat.classes}"/> + <pathelement location="${test.classes}"/> + <pathelement location="${junit.jar}"/> + <pathelement location="${hamcrest.jar}"/> + <path refid="tomcat.classpath" /> + </path> <!-- Version info filter set --> <tstamp> @@ -672,10 +687,161 @@ <delete dir="${tomcat.classes}" /> <delete dir="${tomcat.build}" /> <delete dir="${tomcat.manifests}" /> + <delete dir="${test.classes}" /> + <delete dir="${test.temp}" /> <!-- Remove the copied catalina.properties --> <delete file="java/org/apache/catalina/startup/catalina.properties" /> </target> + <!-- ========================= Testing ========================== --> + + <target name="test-compile" depends="compile" > + <mkdir dir="${test.classes}"/> + <!-- Compile --> + <javac srcdir="test" destdir="${test.classes}" + debug="${compile.debug}" + deprecation="${compile.deprecation}" + source="${compile.source}" + target="${compile.target}" + encoding="ISO-8859-1" + includeantruntime="true"> + <classpath refid="tomcat.test.classpath" /> + <include name="org/apache/**" /> + <include name="javax/**" /> + </javac> + <copy todir="${test.classes}"> + <fileset dir="test"> + <include name="META-INF/**"/> + </fileset> + </copy> + </target> + + <!-- Default JUnit log output formatter --> + <property name="junit.formatter.type" value="plain" /> + <property name="junit.formatter.usefile" value="true" /> + <property name="junit.formatter.extension" value=".txt" /> + + <!-- Workaround against http://bugs.sun.com/view_bug.do?bug_id=6202721 --> + <available file="/dev/urandom" property="test.jvmarg.egd" value="-Djava.security.egd=file:/dev/./urandom"/> + <property name="test.jvmarg.egd" value="" /> + + <target name="test" description="Runs the JUnit test cases" + depends="test-bio,test-nio,test-apr" > + <fileset id="test.result.skippedtests" dir="${test.reports}" includes="*.txt"> + <not> + <contains text="Skipped: 0" /> + </not> + </fileset> + <fileset id="test.result.failedtests" dir="${test.reports}" includes="*.txt"> + <not> + <contains text="Failures: 0, Errors: 0" /> + </not> + </fileset> + <concat> + <header>Testsuites with skipped tests:${line.separator}</header> + <string>${toString:test.result.skippedtests}</string> + <filterchain> + <tokenfilter delimOutput="${line.separator}"> + <stringtokenizer delims=";"/> + </tokenfilter> + </filterchain> + </concat> + <concat> + <header>Testsuites with failed tests:${line.separator}</header> + <string>${toString:test.result.failedtests}</string> + <filterchain> + <tokenfilter delimOutput="${line.separator}"> + <stringtokenizer delims=";"/> + </tokenfilter> + </filterchain> + </concat> + + <fail if="test.result.error" message='Some tests completed with an Error. See ${tomcat.build}/logs for details, search for "ERROR".' /> + <fail if="test.result.failure" message='Some tests completed with a Failure. See ${tomcat.build}/logs for details, search for "FAILED".' /> + </target> + + <target name="test-bio" description="Runs the JUnit test cases for BIO. Does not stop on errors." + depends="test-compile,deploy" if="${execute.test.bio}"> + <runtests protocol="org.apache.coyote.http11.Http11Protocol" + extension=".BIO" /> + </target> + + <target name="test-nio" description="Runs the JUnit test cases for NIO. Does not stop on errors." + depends="test-compile,deploy" if="${execute.test.nio}"> + <runtests protocol="org.apache.coyote.http11.Http11NioProtocol" + extension=".NIO" /> + </target> + + <target name="test-apr" description="Runs the JUnit test cases for APR. Does not stop on errors." + depends="test-compile,deploy,test-apr-exists" + if="${apr.exists}"> + <runtests protocol="org.apache.coyote.http11.Http11AprProtocol" + extension=".APR" /> + </target> + + <target name="test-apr-exists" description="Checks for APR lib" + if="${execute.test.apr}"> + <available file="${test.apr.loc}" property="apr.exists" /> + </target> + + <macrodef name="runtests" + description="Runs the unit tests using the specified connector. + Does not stop on errors, but sets 'test.result.error' and 'test.result.failure' properties."> + <attribute name="protocol" + description="The class name for the connector protocol"/> + <attribute name="extension" + description="The extension to use to distinguish the output"/> + + <sequential> + <mkdir dir="${test.reports}" /> + <junit printsummary="yes" fork="yes" dir="." showoutput="yes" + errorproperty="test.result.error" + failureproperty="test.result.failure" + haltonfailure="${test.haltonfailure}"> + + <jvmarg value="${test.jvmarg.egd}"/> + <jvmarg value="-Djava.library.path=${test.apr.loc}"/> + <jvmarg value="${test.formatter}"/> + <jvmarg value="-Djava.net.preferIPv4Stack=${java.net.preferIPv4Stack}"/> + + <classpath refid="tomcat.test.classpath" /> + + <sysproperty key="tomcat.test.temp" value="${test.temp}" /> + <sysproperty key="tomcat.test.basedir" value="${test.basedir}" /> + <sysproperty key="tomcat.test.tomcatbuild" value="${tomcat.build}" /> + <sysproperty key="tomcat.test.protocol" value="@{protocol}" /> + <sysproperty key="tomcat.test.accesslog" value="${test.accesslog}" /> + <sysproperty key="tomcat.test.reports" value="${test.reports}" /> + <sysproperty key="tomcat.test.openssl.path" value="${test.openssl.path}" /> + <sysproperty key="tomcat.test.relaxTiming" value="${test.relaxTiming}" /> + + <formatter type="${junit.formatter.type}" + usefile="${junit.formatter.usefile}" + extension="@{extension}${junit.formatter.extension}" /> + + <!-- If test.entry is defined, run a single test, otherwise run all valid tests --> + <test todir="${test.reports}" name="${test.entry}" + if="test.entry" unless="test.entry.methods" + /> + <test todir="${test.reports}" name="${test.entry}" methods="${test.entry.methods}" + if="test.entry.methods" + /> + <batchtest todir="${test.reports}" unless="test.entry"> + <fileset dir="test" > + <!-- Include all by default --> + <include name="${test.name}" /> + <!-- Exclude helper classes --> + <exclude name="**/Tester*.java" /> + <!-- Exclude the tests known to fail --> + <exclude name="org/apache/catalina/tribes/test/**" /> + <!-- Exclude performance tests. E.g. on systems with slow/inconsistent timing --> + <exclude name="**/*Performance.java" if="${test.excludePerformance}" /> + </fileset> + </batchtest> + </junit> + </sequential> + </macrodef> + <!-- ================ Download and dependency building =================== --> <target name="proxyflags"> @@ -856,6 +1022,19 @@ <param name="destdir" value="${nsis.home}/.."/> </antcall> + <!-- Libraries used for testing. JUnit, Hamcrest --> + <antcall target="downloadfile"> + <param name="sourcefile" value="${junit.loc}"/> + <param name="destfile" value="${junit.jar}"/> + <param name="destdir" value="${junit.home}"/> + </antcall> + + <antcall target="downloadfile"> + <param name="sourcefile" value="${hamcrest.loc}"/> + <param name="destfile" value="${hamcrest.jar}"/> + <param name="destdir" value="${hamcrest.home}"/> + </antcall> + </target> <target name="build-tomcat-dbcp" unless="jdk16.present" Copied: tomcat/tc6.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java (from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java?p2=tomcat/tc6.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java&p1=tomcat/tc7.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java&r1=1727037&r2=1727049&rev=1727049&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java (original) +++ tomcat/tc6.0.x/trunk/test/org/apache/catalina/connector/TestConnector.java Wed Jan 27 13:37:09 2016 @@ -16,19 +16,12 @@ */ package org.apache.catalina.connector; -import java.net.SocketTimeoutException; +import org.junit.Test; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.Test; - -import org.apache.catalina.Context; -import org.apache.catalina.Wrapper; -import org.apache.catalina.startup.TesterServlet; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; -import org.apache.tomcat.util.buf.ByteChunk; /** * Test cases for {@link Connector}. @@ -36,61 +29,16 @@ import org.apache.tomcat.util.buf.ByteCh public class TestConnector extends TomcatBaseTest { @Test - public void testStop() throws Exception { - Tomcat tomcat = getTomcatInstance(); - - // No file system docBase required - Context root = tomcat.addContext("", null); - Wrapper w = - Tomcat.addServlet(root, "tester", new TesterServlet()); - w.setAsyncSupported(true); - root.addServletMapping("/", "tester"); - - Connector connector = tomcat.getConnector(); - - tomcat.start(); - - ByteChunk bc = new ByteChunk(); - int rc = getUrl("http://localhost:" + getPort() + "/", bc, null, null); - - assertEquals(200, rc); - assertEquals("OK", bc.toString()); - - rc = -1; - bc.recycle(); - - connector.stop(); - - try { - rc = getUrl("http://localhost:" + getPort() + "/", bc, 1000, - null, null); - } catch (SocketTimeoutException ste) { - // May also see this with NIO - // Make sure the test passes if we do - rc = 503; - } - assertEquals(503, rc); - } - - - @Test public void testPort() throws Exception { Tomcat tomcat = getTomcatInstance(); Connector connector1 = tomcat.getConnector(); connector1.setPort(0); - Connector connector2 = new Connector(); - connector2.setPort(0); - - tomcat.getService().addConnector(connector2); - tomcat.start(); int localPort1 = connector1.getLocalPort(); - int localPort2 = connector2.getLocalPort(); assertTrue(localPort1 > 0); - assertTrue(localPort2 > 0); } } Copied: tomcat/tc6.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java (from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java?p2=tomcat/tc6.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java&p1=tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java&r1=1727037&r2=1727049&rev=1727049&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java (original) +++ tomcat/tc6.0.x/trunk/test/org/apache/catalina/core/TestApplicationHttpRequest.java Wed Jan 27 13:37:09 2016 @@ -246,6 +246,7 @@ public class TestApplicationHttpRequest resp.setContentType("text/plain"); resp.setCharacterEncoding("UTF-8"); PrintWriter w = resp.getWriter(); + @SuppressWarnings("unchecked") Map<String,String[]> actual = req.getParameterMap(); boolean ok = true; Copied: tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java (from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java?p2=tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java&p1=tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java&r1=1727037&r2=1727049&rev=1727049&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java (original) +++ tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/CaseInsensitiveKeyMap.java Wed Jan 27 13:37:09 2016 @@ -115,18 +115,15 @@ public class CaseInsensitiveKeyMap<V> ex this.iterator = iterator; } - @Override public boolean hasNext() { return iterator.hasNext(); } - @Override public Entry<String,V> next() { Entry<Key,V> entry = iterator.next(); return new EntryImpl<V>(entry.getKey().getKey(), entry.getValue()); } - @Override public void remove() { iterator.remove(); } @@ -143,17 +140,14 @@ public class CaseInsensitiveKeyMap<V> ex this.value = value; } - @Override public String getKey() { return key; } - @Override public V getValue() { return value; } - @Override public V setValue(V value) { throw new UnsupportedOperationException(); } Copied: tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java (from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java?p2=tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java&p1=tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java&r1=1727037&r2=1727049&rev=1727049&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java (original) +++ tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TestTomcat.java Wed Jan 27 13:37:09 2016 @@ -23,11 +23,6 @@ import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.net.URLConnection; -import java.security.Principal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import javax.naming.InitialContext; @@ -53,8 +48,6 @@ import org.apache.catalina.core.Standard import org.apache.catalina.deploy.ContextEnvironment; import org.apache.catalina.deploy.ContextResourceLink; import org.apache.catalina.ha.context.ReplicatedContext; -import org.apache.catalina.realm.GenericPrincipal; -import org.apache.catalina.realm.RealmBase; import org.apache.tomcat.util.buf.ByteChunk; public class TestTomcat extends TomcatBaseTest { @@ -110,7 +103,9 @@ public class TestTomcat extends TomcatBa (javax.naming.Context) initCtx.lookup("java:comp/env"); name = (String) envCtx.lookup(JNDI_ENV_NAME); } catch (NamingException e) { - throw new IOException(e); + IOException ioe = new IOException(e.getMessage()); + ioe.initCause(e); + throw ioe; } res.getWriter().write("Hello, " + name); @@ -127,7 +122,7 @@ public class TestTomcat extends TomcatBa @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { - URL url = req.getServletContext().getResource("/WEB-INF/web.xml"); + URL url = getServletContext().getResource("/WEB-INF/web.xml"); res.getWriter().write("The URL obtained for /WEB-INF/web.xml was "); if (url == null) { @@ -195,45 +190,45 @@ public class TestTomcat extends TomcatBa } - /** - * Simple Realm that uses a configurable {@link Map} to link user names and - * passwords. - */ - public static final class MapRealm extends RealmBase { - private Map<String,String> users = new HashMap<String,String>(); - private Map<String,List<String>> roles = - new HashMap<String,List<String>>(); - - public void addUser(String username, String password) { - users.put(username, password); - } - - public void addUserRole(String username, String role) { - List<String> userRoles = roles.get(username); - if (userRoles == null) { - userRoles = new ArrayList<String>(); - roles.put(username, userRoles); - } - userRoles.add(role); - } - - @Override - protected String getName() { - return "MapRealm"; - } - - @Override - protected String getPassword(String username) { - return users.get(username); - } - - @Override - protected Principal getPrincipal(String username) { - return new GenericPrincipal(username, getPassword(username), - roles.get(username)); - } - - } +// /** +// * Simple Realm that uses a configurable {@link Map} to link user names and +// * passwords. +// */ +// public static final class MapRealm extends RealmBase { +// private Map<String,String> users = new HashMap<String,String>(); +// private Map<String,List<String>> roles = +// new HashMap<String,List<String>>(); +// +// public void addUser(String username, String password) { +// users.put(username, password); +// } +// +// public void addUserRole(String username, String role) { +// List<String> userRoles = roles.get(username); +// if (userRoles == null) { +// userRoles = new ArrayList<String>(); +// roles.put(username, userRoles); +// } +// userRoles.add(role); +// } +// +// @Override +// protected String getName() { +// return "MapRealm"; +// } +// +// @Override +// protected String getPassword(String username) { +// return users.get(username); +// } +// +// @Override +// protected Principal getPrincipal(String username) { +// return new GenericPrincipal(username, getPassword(username), +// roles.get(username)); +// } +// +// } /** * Start tomcat with a single context and one @@ -248,6 +243,7 @@ public class TestTomcat extends TomcatBa // No file system docBase required Context ctx = tomcat.addContext("", null); + // You can customize the context by calling // its API @@ -265,7 +261,7 @@ public class TestTomcat extends TomcatBa Tomcat tomcat = getTomcatInstance(); File appDir = new File(getBuildDirectory(), "webapps/examples"); - // app dir is relative to server home + tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); tomcat.start(); @@ -464,95 +460,97 @@ public class TestTomcat extends TomcatBa assertNull(tomcat.getWebappConfigFile("test/deployment/dirNoContext", "")); } - @Test - public void testGetWebappConfigFileFromJar() { - Tomcat tomcat = new Tomcat(); - assertNotNull(tomcat.getWebappConfigFile("test/deployment/context.war", "")); - } - - @Test - public void testGetWebappConfigFileFromJarNegative() { - Tomcat tomcat = new Tomcat(); - assertNull(tomcat.getWebappConfigFile("test/deployment/noContext.war", "")); - } +// Reading context.xml from a war file without copying it +// is not implemented in Tomcat 6. (BZ 48662, r928380) +// @Test +// public void testGetWebappConfigFileFromJar() { +// Tomcat tomcat = new Tomcat(); +// assertNotNull(tomcat.getWebappConfigFile("test/deployment/context.war", "")); +// } +// +// @Test +// public void testGetWebappConfigFileFromJarNegative() { +// Tomcat tomcat = new Tomcat(); +// assertNull(tomcat.getWebappConfigFile("test/deployment/noContext.war", "")); +// } +// +// @Test +// public void testBug51526() throws Exception { +// Tomcat tomcat = getTomcatInstance(); +// +// File appFile = new File("test/deployment/context.war"); +// StandardContext context = (StandardContext) tomcat.addWebapp(null, "/test", +// appFile.getAbsolutePath()); +// +// tomcat.start(); +// +// assertEquals("WAR_CONTEXT", context.getSessionCookieName()); +// } +// +// @Test +// public void testGetDefaultContextPerAddWebapp() { +// Tomcat tomcat = getTomcatInstance(); +// +// File appFile = new File("test/deployment/context.war"); +// Context context = tomcat.addWebapp(null, +// "/test", appFile.getAbsolutePath()); +// +// assertEquals(StandardContext.class.getName(), context.getClass() +// .getName()); +// } +// +// @Test +// public void testGetBrokenContextPerAddWepapp() { +// Tomcat tomcat = getTomcatInstance(); +// Host host = tomcat.getHost(); +// if (host instanceof StandardHost) { +// ((StandardHost) host).setContextClass("InvalidContextClassName"); +// } +// +// try { +// File appFile = new File("test/deployment/context.war"); +// tomcat.addWebapp(null, "/test", appFile.getAbsolutePath()); +// fail(); +// } catch (IllegalArgumentException e) { +// // OK +// } +// } +// +// @Test +// public void testGetCustomContextPerAddWebappWithNullHost() { +// Tomcat tomcat = getTomcatInstance(); +// Host host = tomcat.getHost(); +// if (host instanceof StandardHost) { +// ((StandardHost) host).setContextClass(ReplicatedContext.class +// .getName()); +// } +// +// File appFile = new File("test/deployment/context.war"); +// Context context = tomcat.addWebapp(null, "/test", +// appFile.getAbsolutePath()); +// +// assertEquals(ReplicatedContext.class.getName(), context.getClass() +// .getName()); +// } +// +// @Test +// public void testGetCustomContextPerAddWebappWithHost() { +// Tomcat tomcat = getTomcatInstance(); +// Host host = tomcat.getHost(); +// if (host instanceof StandardHost) { +// ((StandardHost) host).setContextClass(ReplicatedContext.class +// .getName()); +// } +// +// File appFile = new File("test/deployment/context.war"); +// Context context = tomcat.addWebapp(host, "/test", +// appFile.getAbsolutePath()); +// +// assertEquals(ReplicatedContext.class.getName(), context.getClass() +// .getName()); +// } @Test - public void testBug51526() throws Exception { - Tomcat tomcat = getTomcatInstance(); - - File appFile = new File("test/deployment/context.war"); - StandardContext context = (StandardContext) tomcat.addWebapp(null, "/test", - appFile.getAbsolutePath()); - - tomcat.start(); - - assertEquals("WAR_CONTEXT", context.getSessionCookieName()); - } - - @Test - public void testGetDefaultContextPerAddWebapp() { - Tomcat tomcat = getTomcatInstance(); - - File appFile = new File("test/deployment/context.war"); - Context context = tomcat.addWebapp(null, - "/test", appFile.getAbsolutePath()); - - assertEquals(StandardContext.class.getName(), context.getClass() - .getName()); - } - - @Test - public void testGetBrokenContextPerAddWepapp() { - Tomcat tomcat = getTomcatInstance(); - Host host = tomcat.getHost(); - if (host instanceof StandardHost) { - ((StandardHost) host).setContextClass("InvalidContextClassName"); - } - - try { - File appFile = new File("test/deployment/context.war"); - tomcat.addWebapp(null, "/test", appFile.getAbsolutePath()); - fail(); - } catch (IllegalArgumentException e) { - // OK - } - } - - @Test - public void testGetCustomContextPerAddWebappWithNullHost() { - Tomcat tomcat = getTomcatInstance(); - Host host = tomcat.getHost(); - if (host instanceof StandardHost) { - ((StandardHost) host).setContextClass(ReplicatedContext.class - .getName()); - } - - File appFile = new File("test/deployment/context.war"); - Context context = tomcat.addWebapp(null, "/test", - appFile.getAbsolutePath()); - - assertEquals(ReplicatedContext.class.getName(), context.getClass() - .getName()); - } - - @Test - public void testGetCustomContextPerAddWebappWithHost() { - Tomcat tomcat = getTomcatInstance(); - Host host = tomcat.getHost(); - if (host instanceof StandardHost) { - ((StandardHost) host).setContextClass(ReplicatedContext.class - .getName()); - } - - File appFile = new File("test/deployment/context.war"); - Context context = tomcat.addWebapp(host, "/test", - appFile.getAbsolutePath()); - - assertEquals(ReplicatedContext.class.getName(), context.getClass() - .getName()); - } - - @Test public void testGetDefaultContextPerAddContext() { Tomcat tomcat = getTomcatInstance(); Copied: tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/Tomcat.java (from r1727037, tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/Tomcat.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/Tomcat.java?p2=tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/Tomcat.java&p1=tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/Tomcat.java&r1=1727037&r2=1727049&rev=1727049&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/Tomcat.java (original) +++ tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/Tomcat.java Wed Jan 27 13:37:09 2016 @@ -19,18 +19,7 @@ package org.apache.catalina.startup; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.Principal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Stack; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.servlet.Servlet; import javax.servlet.ServletException; @@ -44,11 +33,9 @@ import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; -import org.apache.catalina.Realm; import org.apache.catalina.Server; import org.apache.catalina.Service; import org.apache.catalina.Wrapper; -import org.apache.catalina.authenticator.NonLoginAuthenticator; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.NamingContextListener; import org.apache.catalina.core.StandardContext; @@ -57,9 +44,6 @@ import org.apache.catalina.core.Standard import org.apache.catalina.core.StandardServer; import org.apache.catalina.core.StandardService; import org.apache.catalina.core.StandardWrapper; -import org.apache.catalina.deploy.LoginConfig; -import org.apache.catalina.realm.GenericPrincipal; -import org.apache.catalina.realm.RealmBase; // TODO: lazy init for the temp dir - only when a JSP is compiled or // get temp dir is called we need to create it. This will avoid the @@ -125,20 +109,21 @@ import org.apache.catalina.realm.RealmBa * @author Costin Manolache */ public class Tomcat { - // Some logging implementations use weak references for loggers so there is - // the possibility that logging configuration could be lost if GC runs just - // after Loggers are configured but before they are used. The purpose of - // this Map is to retain strong references to explicitly configured loggers - // so that configuration is not lost. - private final Map<String, Logger> pinnedLoggers = new HashMap<String, Logger>(); + +// // Some logging implementations use weak references for loggers so there is +// // the possibility that logging configuration could be lost if GC runs just +// // after Loggers are configured but before they are used. The purpose of +// // this Map is to retain strong references to explicitly configured loggers +// // so that configuration is not lost. +// private final Map<String, Logger> pinnedLoggers = new HashMap<String, Logger>(); // Single engine, service, server, connector - few cases need more, // they can use server.xml - protected Server server; - protected Service service; - protected Engine engine; + protected StandardServer server; + protected StandardService service; + protected StandardEngine engine; protected Connector connector; // for more - customize the classes - + // To make it a bit easier to config for the common case // ( one host, one context ). protected Host host; @@ -147,25 +132,28 @@ public class Tomcat { // really needed ? // TODO: allow use of in-memory connector - + protected int port = 8080; protected String hostname = "localhost"; protected String basedir; - - // Default in-memory realm, will be set by default on the Engine. Can be - // replaced at engine level or over-ridden at Host or Context level - @Deprecated // Will be removed in Tomcat 8.0.x. - protected Realm defaultRealm; - private final Map<String, String> userPass = new HashMap<String, String>(); - private final Map<String, List<String>> userRoles = - new HashMap<String, List<String>>(); - private final Map<String, Principal> userPrincipals = - new HashMap<String, Principal>(); - + + private volatile boolean initialized; + private volatile boolean started; + +// // Default in-memory realm, will be set by default on the Engine. Can be +// // replaced at engine level or over-ridden at Host or Context level +// @Deprecated // Will be removed in Tomcat 8.0.x. +// protected Realm defaultRealm; +// private final Map<String, String> userPass = new HashMap<String, String>(); +// private final Map<String, List<String>> userRoles = +// new HashMap<String, List<String>>(); +// private final Map<String, Principal> userPrincipals = +// new HashMap<String, Principal>(); + public Tomcat() { // NOOP } - + /** * Tomcat needs a directory for temp files. This should be the * first method called. @@ -190,7 +178,7 @@ public class Tomcat { public void setPort(int port) { this.port = port; } - + /** * The the hostname of the default host, default is * 'localhost'. @@ -212,8 +200,8 @@ public class Tomcat { public Context addWebapp(String contextPath, String docBase) throws ServletException { return addWebapp(getHost(), contextPath, docBase); } - - + + /** * Add a context - programmatic mode, no web.xml used. * @@ -245,30 +233,30 @@ public class Tomcat { return addContext(getHost(), contextPath, docBase); } - /** - * Equivalent with - * <servlet><servlet-name><servlet-class>. - * - * In general it is better/faster to use the method that takes a - * Servlet as param - this one can be used if the servlet is not - * commonly used, and want to avoid loading all deps. - * ( for example: jsp servlet ) - * - * You can customize the returned servlet, ex: - * - * wrapper.addInitParameter("name", "value"); - * - * @param contextPath Context to add Servlet to - * @param servletName Servlet name (used in mappings) - * @param servletClass The class to be used for the Servlet - * @return The wrapper for the servlet - */ - public Wrapper addServlet(String contextPath, - String servletName, - String servletClass) { - Container ctx = getHost().findChild(contextPath); - return addServlet((Context) ctx, servletName, servletClass); - } +// /** +// * Equivalent with +// * <servlet><servlet-name><servlet-class>. +// * +// * In general it is better/faster to use the method that takes a +// * Servlet as param - this one can be used if the servlet is not +// * commonly used, and want to avoid loading all deps. +// * ( for example: jsp servlet ) +// * +// * You can customize the returned servlet, ex: +// * +// * wrapper.addInitParameter("name", "value"); +// * +// * @param contextPath Context to add Servlet to +// * @param servletName Servlet name (used in mappings) +// * @param servletClass The class to be used for the Servlet +// * @return The wrapper for the servlet +// */ +// public Wrapper addServlet(String contextPath, +// String servletName, +// String servletClass) { +// Container ctx = getHost().findChild(contextPath); +// return addServlet((Context) ctx, servletName, servletClass); +// } /** * Static version of {@link #addServlet(String, String, String)} @@ -289,20 +277,20 @@ public class Tomcat { return sw; } - /** - * Add an existing Servlet to the context with no class.forName or - * initialisation. - * @param contextPath Context to add Servlet to - * @param servletName Servlet name (used in mappings) - * @param servlet The Servlet to add - * @return The wrapper for the servlet - */ - public Wrapper addServlet(String contextPath, - String servletName, - Servlet servlet) { - Container ctx = getHost().findChild(contextPath); - return addServlet((Context) ctx, servletName, servlet); - } +// /** +// * Add an existing Servlet to the context with no class.forName or +// * initialisation. +// * @param contextPath Context to add Servlet to +// * @param servletName Servlet name (used in mappings) +// * @param servlet The Servlet to add +// * @return The wrapper for the servlet +// */ +// public Wrapper addServlet(String contextPath, +// String servletName, +// Servlet servlet) { +// Container ctx = getHost().findChild(contextPath); +// return addServlet((Context) ctx, servletName, servlet); +// } /** * Static version of {@link #addServlet(String, String, Servlet)}. @@ -331,19 +319,30 @@ public class Tomcat { public void init() throws LifecycleException { getServer(); getConnector(); - server.init(); + if (!initialized) { + initialized = true; + try { + server.init(); + } catch (LifecycleException e) { + throw e; + } catch (Exception e) { + throw new LifecycleException(e); + } + } } - - + + /** * Start the server. * * @throws LifecycleException */ public void start() throws LifecycleException { - getServer(); - getConnector(); - server.start(); + if (!started) { + init(); + started = true; + server.start(); + } } /** @@ -352,8 +351,10 @@ public class Tomcat { * @throws LifecycleException */ public void stop() throws LifecycleException { - getServer(); - server.stop(); + if (started) { + started = false; + server.stop(); + } } @@ -362,35 +363,38 @@ public class Tomcat { * called. */ public void destroy() throws LifecycleException { - getServer(); - server.destroy(); - // Could null out objects here - } - - /** - * Add a user for the in-memory realm. All created apps use this - * by default, can be replaced using setRealm(). - * - */ - public void addUser(String user, String pass) { - userPass.put(user, pass); - } - - /** - * @see #addUser(String, String) - */ - public void addRole(String user, String role) { - List<String> roles = userRoles.get(user); - if (roles == null) { - roles = new ArrayList<String>(); - userRoles.put(user, roles); + if (initialized) { + stop(); + initialized = false; + // server.destroy(); + // Could null out objects here } - roles.add(role); } +// /** +// * Add a user for the in-memory realm. All created apps use this +// * by default, can be replaced using setRealm(). +// * +// */ +// public void addUser(String user, String pass) { +// userPass.put(user, pass); +// } +// +// /** +// * @see #addUser(String, String) +// */ +// public void addRole(String user, String role) { +// List<String> roles = userRoles.get(user); +// if (roles == null) { +// roles = new ArrayList<String>(); +// userRoles.put(user, roles); +// } +// roles.add(role); +// } + // ------- Extra customization ------- // You can tune individual tomcat objects, using internal APIs - + /** * Get the default http connector. You can set more * parameters - the port is already initialized. @@ -410,16 +414,24 @@ public class Tomcat { // This creates an APR HTTP connector if AprLifecycleListener has been // configured (created) and Tomcat Native library is available. // Otherwise it creates a BIO HTTP connector (Http11Protocol). - connector = new Connector("HTTP/1.1"); + try { + connector = new Connector("HTTP/1.1"); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + // Never happens. Connector() declares that it can throw + // an Exception, but never throws one. + throw new RuntimeException(e); + } connector.setPort(port); service.addConnector( connector ); return connector; } - + public void setConnector(Connector connector) { this.connector = connector; } - + /** * Get the service object. Can be used to add more * connectors and few other global settings. @@ -439,7 +451,7 @@ public class Tomcat { public void setHost(Host host) { this.host = host; } - + public Host getHost() { if (host == null) { host = new StandardHost(); @@ -449,20 +461,20 @@ public class Tomcat { } return host; } - - /** - * Set a custom realm for auth. If not called, a simple - * default will be used, using an internal map. - * - * Must be called before adding a context. - * - * @deprecated Will be removed in Tomcat 8.0.x. - */ - @Deprecated - public void setDefaultRealm(Realm realm) { - defaultRealm = realm; - } - + +// /** +// * Set a custom realm for auth. If not called, a simple +// * default will be used, using an internal map. +// * +// * Must be called before adding a context. +// * +// * @deprecated Will be removed in Tomcat 8.0.x. +// */ +// @Deprecated +// public void setDefaultRealm(Realm realm) { +// defaultRealm = realm; +// } +// /** * Access to the engine, for further customization. @@ -473,10 +485,11 @@ public class Tomcat { engine = new StandardEngine(); engine.setName( "Tomcat" ); engine.setDefaultHost(hostname); - if (defaultRealm == null) { - initSimpleAuth(); - } - engine.setRealm(defaultRealm); + // @Deprecated + // if (defaultRealm == null) { + // initSimpleAuth(); + // } + // engine.setRealm(defaultRealm); service.setContainer(engine); } return engine; @@ -487,21 +500,21 @@ public class Tomcat { * customizations. JNDI is disabled by default. */ public Server getServer() { - + if (server != null) { return server; } - - initBaseDir(); - + + initBaseDir(); + System.setProperty("catalina.useNaming", "false"); - + server = new StandardServer(); - server.setPort( -1 ); - + server.setPort(-1); + service = new StandardService(); service.setName("Tomcat"); - server.addService( service ); + server.addService(service); return server; } @@ -509,15 +522,15 @@ public class Tomcat { return addContext(host, contextPath, contextPath, dir); } - public Context addContext(Host host, String contextPath, String contextName, + private Context addContext(Host host, String contextPath, String contextName, String dir) { - silence(host, contextPath); +// silence(host, contextPath); Context ctx = createContext(host, contextPath); ctx.setName(contextName); ctx.setPath(contextPath); ctx.setDocBase(dir); - ctx.addLifecycleListener(new FixContextListener()); - + ((Lifecycle) ctx).addLifecycleListener(new FixContextListener()); + if (host == null) { getHost().addChild(ctx); } else { @@ -538,21 +551,21 @@ public class Tomcat { * @deprecated Use {@link #addWebapp(Host, String, String)} */ @Deprecated - public Context addWebapp(Host host, String contextPath, String name, String docBase) { - silence(host, contextPath); + private Context addWebapp(Host host, String contextPath, String name, String docBase) { +// silence(host, contextPath); Context ctx = createContext(host, contextPath); ctx.setPath(contextPath); ctx.setDocBase(docBase); - ctx.addLifecycleListener(new DefaultWebXmlListener()); + ((Lifecycle) ctx).addLifecycleListener(new DefaultWebXmlListener()); ctx.setConfigFile(getWebappConfigFile(docBase, contextPath)); ContextConfig ctxCfg = new ContextConfig(); - ctx.addLifecycleListener(ctxCfg); - - // prevent it from looking ( if it finds one - it'll have dup error ) - ctxCfg.setDefaultWebXml(noDefaultWebXmlPath()); + ((Lifecycle) ctx).addLifecycleListener(ctxCfg); + +// // prevent it from looking ( if it finds one - it'll have dup error ) +// ctxCfg.setDefaultWebXml(noDefaultWebXmlPath()); if (host == null) { getHost().addChild(ctx); @@ -563,81 +576,81 @@ public class Tomcat { return ctx; } - /** - * Return a listener that provides the required configuration items for JSP - * processing. From the standard Tomcat global web.xml. Pass this to - * {@link Context#addLifecycleListener(LifecycleListener)} and then pass the - * result of {@link #noDefaultWebXmlPath()} to - * {@link ContextConfig#setDefaultWebXml(String)}. - * @return a listener object that configures default JSP processing. - */ - public LifecycleListener getDefaultWebXmlListener() { - return new DefaultWebXmlListener(); - } - - /** - * @return a pathname to pass to - * {@link ContextConfig#setDefaultWebXml(String)} when using - * {@link #getDefaultWebXmlListener()}. - */ - public String noDefaultWebXmlPath() { - return Constants.NoDefaultWebXml; - } - - /** - * For complex configurations, this accessor allows callers of this class - * to obtain the simple realm created by default. - * @return the simple in-memory realm created by default. - * @deprecated Will be removed in Tomcat 8.0.x - */ - @Deprecated - public Realm getDefaultRealm() { - if (defaultRealm == null) { - initSimpleAuth(); - } - return defaultRealm; - } +// /** +// * Return a listener that provides the required configuration items for JSP +// * processing. From the standard Tomcat global web.xml. Pass this to +// * {@link Context#addLifecycleListener(LifecycleListener)} and then pass the +// * result of {@link #noDefaultWebXmlPath()} to +// * {@link ContextConfig#setDefaultWebXml(String)}. +// * @return a listener object that configures default JSP processing. +// */ +// public LifecycleListener getDefaultWebXmlListener() { +// return new DefaultWebXmlListener(); +// } +// +// /** +// * @return a pathname to pass to +// * {@link ContextConfig#setDefaultWebXml(String)} when using +// * {@link #getDefaultWebXmlListener()}. +// */ +// public String noDefaultWebXmlPath() { +// return Constants.NoDefaultWebXml; +// } +// +// /** +// * For complex configurations, this accessor allows callers of this class +// * to obtain the simple realm created by default. +// * @return the simple in-memory realm created by default. +// * @deprecated Will be removed in Tomcat 8.0.x +// */ +// @Deprecated +// public Realm getDefaultRealm() { +// if (defaultRealm == null) { +// initSimpleAuth(); +// } +// return defaultRealm; +// } +// +// +// // ---------- Helper methods and classes ------------------- +// +// /** +// * Create an in-memory realm. You can replace it for contexts with a real +// * one. The Realm created here will be added to the Engine by default and +// * may be replaced at the Engine level or over-ridden (as per normal Tomcat +// * behaviour) at the Host or Context level. +// * @deprecated Will be removed in Tomcat 8.0.x +// */ +// @Deprecated +// protected void initSimpleAuth() { +// defaultRealm = new RealmBase() { +// @Override +// protected String getName() { +// return "Simple"; +// } +// +// @Override +// protected String getPassword(String username) { +// return userPass.get(username); +// } +// +// @Override +// protected Principal getPrincipal(String username) { +// Principal p = userPrincipals.get(username); +// if (p == null) { +// String pass = userPass.get(username); +// if (pass != null) { +// p = new GenericPrincipal(username, pass, +// userRoles.get(username)); +// userPrincipals.put(username, p); +// } +// } +// return p; +// } +// +// }; +// } - - // ---------- Helper methods and classes ------------------- - - /** - * Create an in-memory realm. You can replace it for contexts with a real - * one. The Realm created here will be added to the Engine by default and - * may be replaced at the Engine level or over-ridden (as per normal Tomcat - * behaviour) at the Host or Context level. - * @deprecated Will be removed in Tomcat 8.0.x - */ - @Deprecated - protected void initSimpleAuth() { - defaultRealm = new RealmBase() { - @Override - protected String getName() { - return "Simple"; - } - - @Override - protected String getPassword(String username) { - return userPass.get(username); - } - - @Override - protected Principal getPrincipal(String username) { - Principal p = userPrincipals.get(username); - if (p == null) { - String pass = userPass.get(username); - if (pass != null) { - p = new GenericPrincipal(username, pass, - userRoles.get(username)); - userPrincipals.put(username, p); - } - } - return p; - } - - }; - } - protected void initBaseDir() { String catalinaHome = System.getProperty(Globals.CATALINA_HOME_PROP); if (basedir == null) { @@ -648,8 +661,7 @@ public class Tomcat { } if (basedir == null) { // Create a temp dir. - basedir = System.getProperty("user.dir") + - "/tomcat." + port; + basedir = System.getProperty("user.dir") + "/tomcat." + port; File home = new File(basedir); home.mkdir(); if (!home.isAbsolute()) { @@ -666,54 +678,56 @@ public class Tomcat { System.setProperty(Globals.CATALINA_BASE_PROP, basedir); } - static final String[] silences = new String[] { - "org.apache.coyote.http11.Http11Protocol", - "org.apache.catalina.core.StandardService", - "org.apache.catalina.core.StandardEngine", - "org.apache.catalina.startup.ContextConfig", - "org.apache.catalina.core.ApplicationContext", - "org.apache.catalina.core.AprLifecycleListener" - }; - - /** - * Controls if the loggers will be silenced or not. - * @param silent <code>true</code> sets the log level to WARN for the - * loggers that log information on Tomcat start up. This - * prevents the usual startup information being logged. - * <code>false</code> sets the log level to the default - * level of INFO. - */ - public void setSilent(boolean silent) { - for (String s : silences) { - Logger logger = Logger.getLogger(s); - pinnedLoggers.put(s, logger); - if (silent) { - logger.setLevel(Level.WARNING); - } else { - logger.setLevel(Level.INFO); - } - } - } - - private void silence(Host host, String ctx) { - String loggerName = getLoggerName(host, ctx); - Logger logger = Logger.getLogger(loggerName); - pinnedLoggers.put(loggerName, logger); - logger.setLevel(Level.WARNING); - } - - private String getLoggerName(Host host, String ctx) { - String loggerName = "org.apache.catalina.core.ContainerBase.[default].["; - if (host == null) { - loggerName += getHost().getName(); - } else { - loggerName += host.getName(); - } - loggerName += "].["; - loggerName += ctx; - loggerName += "]"; - return loggerName; - } +// Not needed. See BZ 58905. +// +// static final String[] silences = new String[] { +// "org.apache.coyote.http11.Http11Protocol", +// "org.apache.catalina.core.StandardService", +// "org.apache.catalina.core.StandardEngine", +// "org.apache.catalina.startup.ContextConfig", +// "org.apache.catalina.core.ApplicationContext", +// "org.apache.catalina.core.AprLifecycleListener" +// }; +// +// /** +// * Controls if the loggers will be silenced or not. +// * @param silent <code>true</code> sets the log level to WARN for the +// * loggers that log information on Tomcat start up. This +// * prevents the usual startup information being logged. +// * <code>false</code> sets the log level to the default +// * level of INFO. +// */ +// public void setSilent(boolean silent) { +// for (String s : silences) { +// Logger logger = Logger.getLogger(s); +// pinnedLoggers.put(s, logger); +// if (silent) { +// logger.setLevel(Level.WARNING); +// } else { +// logger.setLevel(Level.INFO); +// } +// } +// } +// +// private void silence(Host host, String ctx) { +// String loggerName = getLoggerName(host, ctx); +// Logger logger = Logger.getLogger(loggerName); +// pinnedLoggers.put(loggerName, logger); +// logger.setLevel(Level.WARNING); +// } +// +// private String getLoggerName(Host host, String ctx) { +// String loggerName = "org.apache.catalina.core.ContainerBase.[default].["; +// if (host == null) { +// loggerName += getHost().getName(); +// } else { +// loggerName += host.getName(); +// } +// loggerName += "].["; +// loggerName += ctx; +// loggerName += "]"; +// return loggerName; +// } /** * Create the configured {@link Context} for the given <code>host</code>. @@ -787,7 +801,7 @@ public class Tomcat { // disabled getServer(); server.addLifecycleListener(new NamingContextListener()); - + System.setProperty("catalina.useNaming", "true"); String value = "org.apache.naming"; @@ -811,19 +825,19 @@ public class Tomcat { } } - /** - * Provide default configuration for a context. This is the programmatic - * equivalent of the default web.xml. - * - * TODO: in normal Tomcat, if default-web.xml is not found, use this - * method - * - * @param contextPath The context to set the defaults for - */ - public void initWebappDefaults(String contextPath) { - Container ctx = getHost().findChild(contextPath); - initWebappDefaults((Context) ctx); - } +// /** +// * Provide default configuration for a context. This is the programmatic +// * equivalent of the default web.xml. +// * +// * TODO: in normal Tomcat, if default-web.xml is not found, use this +// * method +// * +// * @param contextPath The context to set the defaults for +// */ +// public void initWebappDefaults(String contextPath) { +// Container ctx = getHost().findChild(contextPath); +// initWebappDefaults((Context) ctx); +// } /** * Static version of {@link #initWebappDefaults(String)} @@ -834,14 +848,14 @@ public class Tomcat { Wrapper servlet = addServlet( ctx, "default", "org.apache.catalina.servlets.DefaultServlet"); servlet.setLoadOnStartup(1); - servlet.setOverridable(true); + //servlet.setOverridable(true); // JSP servlet (by class name - to avoid loading all deps) servlet = addServlet( ctx, "jsp", "org.apache.jasper.servlet.JspServlet"); servlet.addInitParameter("fork", "false"); servlet.setLoadOnStartup(3); - servlet.setOverridable(true); + //servlet.setOverridable(true); // Servlet mappings ctx.addServletMapping("/", "default"); @@ -872,20 +886,21 @@ public class Tomcat { */ public static class FixContextListener implements LifecycleListener { - @Override public void lifecycleEvent(LifecycleEvent event) { try { Context context = (Context) event.getLifecycle(); - if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { + // Using START_EVENT, Tomcat 7+ uses CONFIGURE_START_EVENT here. + if (event.getType().equals(Lifecycle.START_EVENT)) { context.setConfigured(true); } - // LoginConfig is required to process @ServletSecurity - // annotations - if (context.getLoginConfig() == null) { - context.setLoginConfig( - new LoginConfig("NONE", null, null, null)); - context.getPipeline().addValve(new NonLoginAuthenticator()); - } +// Not needed. Tomcat 6 does not support @ServletSecurity annotations. +// // LoginConfig is required to process @ServletSecurity +// // annotations +// if (context.getLoginConfig() == null) { +// context.setLoginConfig( +// new LoginConfig("NONE", null, null, null)); +// context.getPipeline().addValve(new NonLoginAuthenticator()); +// } } catch (ClassCastException e) { return; } @@ -900,7 +915,6 @@ public class Tomcat { * listener sets the equivalent of conf/web.xml when the context starts. */ public static class DefaultWebXmlListener implements LifecycleListener { - @Override public void lifecycleEvent(LifecycleEvent event) { if (Lifecycle.BEFORE_START_EVENT.equals(event.getType())) { initWebappDefaults((Context) event.getLifecycle()); @@ -916,6 +930,8 @@ public class Tomcat { */ public static class ExistingStandardWrapper extends StandardWrapper { private final Servlet existing; + private boolean instanceInitialized = false; + private static final long serialVersionUID = 1L; @SuppressWarnings("deprecation") public ExistingStandardWrapper( Servlet existing ) { @@ -1143,51 +1159,49 @@ public class Tomcat { "zip", "application/zip" }; - protected URL getWebappConfigFile(String path, String url) { + protected String getWebappConfigFile(String path, @SuppressWarnings("unused") String contextPath) { File docBase = new File(path); if (docBase.isDirectory()) { - return getWebappConfigFileFromDirectory(docBase, url); + return getWebappConfigFileFromDirectory(docBase); } else { - return getWebappConfigFileFromJar(docBase, url); + // Reading context.xml from a war file without copying it + // is not implemented in Tomcat 6. (BZ 48662, r928380) + // return getWebappConfigFileFromJar(docBase, contextPath); + return null; } } - private URL getWebappConfigFileFromDirectory(File docBase, String url) { - URL result = null; + private String getWebappConfigFileFromDirectory(File docBase) { + String result = null; File webAppContextXml = new File(docBase, Constants.ApplicationContextXml); if (webAppContextXml.exists()) { - try { - result = webAppContextXml.toURI().toURL(); - } catch (MalformedURLException e) { - Logger.getLogger(getLoggerName(getHost(), url)).log(Level.WARNING, - "Unable to determine web application context.xml " + docBase, e); - } + result = webAppContextXml.getAbsolutePath(); } return result; } - private URL getWebappConfigFileFromJar(File docBase, String url) { - URL result = null; - JarFile jar = null; - try { - jar = new JarFile(docBase); - JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml); - if (entry != null) { - result = new URL("jar:" + docBase.toURI().toString() + "!/" - + Constants.ApplicationContextXml); - } - } catch (IOException e) { - Logger.getLogger(getLoggerName(getHost(), url)).log(Level.WARNING, - "Unable to determine web application context.xml " + docBase, e); - } finally { - if (jar != null) { - try { - jar.close(); - } catch (IOException e) { - // ignore - } - } - } - return result; - } +// private URL getWebappConfigFileFromJar(File docBase, String url) { +// URL result = null; +// JarFile jar = null; +// try { +// jar = new JarFile(docBase); +// JarEntry entry = jar.getJarEntry(Constants.ApplicationContextXml); +// if (entry != null) { +// result = new URL("jar:" + docBase.toURI().toString() + "!/" +// + Constants.ApplicationContextXml); +// } +// } catch (IOException e) { +// Logger.getLogger(getLoggerName(getHost(), url)).log(Level.WARNING, +// "Unable to determine web application context.xml " + docBase, e); +// } finally { +// if (jar != null) { +// try { +// jar.close(); +// } catch (IOException e) { +// // ignore +// } +// } +// } +// return result; +// } } Copied: tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java (from r1727037, tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java) URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java?p2=tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java&p1=tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java&r1=1727037&r2=1727049&rev=1727049&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java (original) +++ tomcat/tc6.0.x/trunk/test/org/apache/catalina/startup/TomcatBaseTest.java Wed Jan 27 13:37:09 2016 @@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletReq import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import org.junit.After; @@ -45,9 +46,9 @@ import org.junit.Before; import org.apache.catalina.Container; import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleState; import org.apache.catalina.Manager; import org.apache.catalina.Server; +import org.apache.catalina.ServerFactory; import org.apache.catalina.Service; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.AprLifecycleListener; @@ -101,6 +102,11 @@ public abstract class TomcatBaseTest ext fail("Unable to create appBase for test"); } + // A sanity check that the Server reference has been cleared after + // the previous test run + assertNull("A Server has already been created.", + ServerFactory.getServer(false)); + tomcat = new TomcatWithFastSessionIDs(); String protocol = getProtocol(); @@ -165,17 +171,12 @@ public abstract class TomcatBaseTest ext @Override public void tearDown() throws Exception { try { - // Some tests may call tomcat.destroy(), some tests may just call - // tomcat.stop(), some not call either method. Make sure that stop() - // & destroy() are called as necessary. - if (tomcat.server != null - && tomcat.server.getState() != LifecycleState.DESTROYED) { - if (tomcat.server.getState() != LifecycleState.STOPPED) { - tomcat.stop(); - } + if (tomcat.server != null) { + tomcat.stop(); tomcat.destroy(); } } finally { + ServerFactory.clear(); super.tearDown(); } } @@ -398,7 +399,7 @@ public abstract class TomcatBaseTest ext private static final long serialVersionUID = 1L; - @SuppressWarnings("deprecation") + @SuppressWarnings({ "deprecation", "unchecked" }) @Override public void service(HttpServletRequest request, HttpServletResponse response) @@ -783,7 +784,7 @@ public abstract class TomcatBaseTest ext c.setManager(m); } if (m instanceof ManagerBase) { - ((ManagerBase) m).setSecureRandomClass( + ((ManagerBase) m).setRandomClass( "org.apache.catalina.startup.FastNonSecureRandom"); } } Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1727049&r1=1727048&r2=1727049&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Wed Jan 27 13:37:09 2016 @@ -220,6 +220,10 @@ Update the NSIS Installer used to build the Windows Installers to version 2.50. (markt/kkolinko) </update> + <add> + Add framework for client-server unit tests, porting it from + Tomcat 7. Add support for running the tests with Apache Ant. (kkolinko) + </add> </changelog> </subsection> </section> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org