Added: tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff?rev=1726112&view=auto
==============================================================================
--- tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff (added)
+++ tomcat/tc6.0.x/branches/tomcat6-testing_20160106/BRANCH-diff.diff Thu Jan 
21 21:55:19 2016
@@ -0,0 +1,3922 @@
+Index: test/build.xml
+===================================================================
+--- test/build.xml     (.../trunk)     (revision 1726111)
++++ test/build.xml     (.../branches/tomcat6-testing_20160106) (revision 
1726111)
+@@ -1,71 +0,0 @@
+-<?xml version="1.0"?>
+-<!--
+- Licensed to the Apache Software Foundation (ASF) under one or more
+-  contributor license agreements.  See the NOTICE file distributed with
+-  this work for additional information regarding copyright ownership.
+-  The ASF licenses this file to You under the Apache License, Version 2.0
+-  (the "License"); you may not use this file except in compliance with
+-  the License.  You may obtain a copy of the License at
+-
+-      http://www.apache.org/licenses/LICENSE-2.0
+-
+-  Unless required by applicable law or agreed to in writing, software
+-  distributed under the License is distributed on an "AS IS" BASIS,
+-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-  See the License for the specific language governing permissions and
+-  limitations under the License.
+--->
+-<project name="Tomcat 6.0" default="all" basedir=".">
+-
+-  <!-- See "build.properties.sample" in the top level directory for all     
-->
+-  <!-- property values you must customize for successful building!!!        
-->
+-  <property file="${user.home}/build.properties"/>
+-  <property file="build.properties"/>
+-
+-  <property file="build.properties.default"/>
+-
+-  <property name="test.classes" value="${basedir}/output/classes"/>
+-  <property name="tomcat.build" value="${basedir}/../output/build"/>
+-
+-  <property name="compile.source" value="1.5"/>
+-  <property name="compile.debug" value="true"/>
+-
+-  <property name="junit.jar" value="${junit.home}/junit.jar"/>
+-  <property name="test.runner" value="junit.textui.TestRunner"/>
+-
+-  <path id="tomcat.test.classpath">
+-    <pathelement location="${test.classes}"/>
+-    <pathelement location="${junit.jar}"/>
+-    <fileset dir="${tomcat.build}/lib/">
+-      <include name="tomcat-coyote.jar"/>
+-    </fileset>
+-    <fileset dir="${tomcat.build}/bin/">
+-      <include name="tomcat-juli.jar"/>
+-    </fileset>
+-  </path>
+-
+-  <target name="compile">
+-
+-  <mkdir dir="${test.classes}"/>
+-
+-  <!-- Compile -->
+-  <javac srcdir="." destdir="${test.classes}"
+-         debug="${compile.debug}"
+-         deprecation="${compile.deprecation}"
+-         source="${compile.source}"
+-         optimize="${compile.optimize}"
+-         encoding="ISO-8859-1">
+-         <classpath refid="tomcat.test.classpath" />
+-         <include name="org/apache/tomcat/util/**" />
+-  </javac>
+-
+-  </target>
+-
+-  <target name="all" depends="compile">
+-     <java dir="${test.classes}" classname="${test.runner}" fork="yes" 
failonerror="${test.failonerror}">
+-            <arg value="org.apache.tomcat.util.http.TestCookies"/>
+-            <classpath refid="tomcat.test.classpath"/>
+-        </java>
+-
+-  </target>
+-</project>
+Index: test/deployment/dirNoContext/index.html
+===================================================================
+--- test/deployment/dirNoContext/index.html    (.../trunk)     (revision 0)
++++ test/deployment/dirNoContext/index.html    
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,22 @@
++<!--
++  Licensed to the Apache Software Foundation (ASF) under one or more
++  contributor license agreements.  See the NOTICE file distributed with
++  this work for additional information regarding copyright ownership.
++  The ASF licenses this file to You under the Apache License, Version 2.0
++  (the "License"); you may not use this file except in compliance with
++  the License.  You may obtain a copy of the License at
++
++      http://www.apache.org/licenses/LICENSE-2.0
++
++  Unless required by applicable law or agreed to in writing, software
++  distributed under the License is distributed on an "AS IS" BASIS,
++  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++  See the License for the specific language governing permissions and
++  limitations under the License.
++-->
++<!-- dirNoContext -->
++<html>
++  <body>
++    <p>Directory based web application with no context.xml file.</p>
++  </body>
++</html>
+\ No newline at end of file
+
+Property changes on: test/deployment/dirNoContext/index.html
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/deployment/dirContext/index.html
+===================================================================
+--- test/deployment/dirContext/index.html      (.../trunk)     (revision 0)
++++ test/deployment/dirContext/index.html      
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,22 @@
++<!--
++  Licensed to the Apache Software Foundation (ASF) under one or more
++  contributor license agreements.  See the NOTICE file distributed with
++  this work for additional information regarding copyright ownership.
++  The ASF licenses this file to You under the Apache License, Version 2.0
++  (the "License"); you may not use this file except in compliance with
++  the License.  You may obtain a copy of the License at
++
++      http://www.apache.org/licenses/LICENSE-2.0
++
++  Unless required by applicable law or agreed to in writing, software
++  distributed under the License is distributed on an "AS IS" BASIS,
++  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++  See the License for the specific language governing permissions and
++  limitations under the License.
++-->
++<!-- dirContext -->
++<html>
++  <body>
++    <p>Directory based web application with a context.xml file.</p>
++  </body>
++</html>
+\ No newline at end of file
+
+Property changes on: test/deployment/dirContext/index.html
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/deployment/dirContext/META-INF/context.xml
+===================================================================
+--- test/deployment/dirContext/META-INF/context.xml    (.../trunk)     
(revision 0)
++++ test/deployment/dirContext/META-INF/context.xml    
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,17 @@
++<!--
++  Licensed to the Apache Software Foundation (ASF) under one or more
++  contributor license agreements.  See the NOTICE file distributed with
++  this work for additional information regarding copyright ownership.
++  The ASF licenses this file to You under the Apache License, Version 2.0
++  (the "License"); you may not use this file except in compliance with
++  the License.  You may obtain a copy of the License at
++
++      http://www.apache.org/licenses/LICENSE-2.0
++
++  Unless required by applicable law or agreed to in writing, software
++  distributed under the License is distributed on an "AS IS" BASIS,
++  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++  See the License for the specific language governing permissions and
++  limitations under the License.
++-->
++<Context sessionCookieName="DIR_CONTEXT" />
+\ No newline at end of file
+
+Property changes on: test/deployment/dirContext/META-INF/context.xml
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/org/apache/catalina/connector/TestConnector.java
+===================================================================
+--- test/org/apache/catalina/connector/TestConnector.java      (.../trunk)     
(revision 0)
++++ test/org/apache/catalina/connector/TestConnector.java      
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,44 @@
++/*
++ *  Licensed to the Apache Software Foundation (ASF) under one or more
++ *  contributor license agreements.  See the NOTICE file distributed with
++ *  this work for additional information regarding copyright ownership.
++ *  The ASF licenses this file to You under the Apache License, Version 2.0
++ *  (the "License"); you may not use this file except in compliance with
++ *  the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *  Unless required by applicable law or agreed to in writing, software
++ *  distributed under the License is distributed on an "AS IS" BASIS,
++ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ *  See the License for the specific language governing permissions and
++ *  limitations under the License.
++ */
++package org.apache.catalina.connector;
++
++import org.junit.Test;
++
++import static org.junit.Assert.assertTrue;
++
++import org.apache.catalina.startup.Tomcat;
++import org.apache.catalina.startup.TomcatBaseTest;
++
++/**
++ * Test cases for {@link Connector}.
++ */
++public class TestConnector extends TomcatBaseTest {
++
++    @Test
++    public void testPort() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        Connector connector1 = tomcat.getConnector();
++        connector1.setPort(0);
++
++        tomcat.start();
++
++        int localPort1 = connector1.getLocalPort();
++
++        assertTrue(localPort1 > 0);
++    }
++}
+
+Property changes on: test/org/apache/catalina/connector/TestConnector.java
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/org/apache/catalina/startup/TestTomcat.java
+===================================================================
+--- test/org/apache/catalina/startup/TestTomcat.java   (.../trunk)     
(revision 0)
++++ test/org/apache/catalina/startup/TestTomcat.java   
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,594 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.catalina.startup;
++
++import java.io.File;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.InputStreamReader;
++import java.io.Reader;
++import java.net.URL;
++import java.net.URLConnection;
++import java.util.concurrent.atomic.AtomicInteger;
++
++import javax.naming.InitialContext;
++import javax.naming.NamingException;
++import javax.servlet.ServletException;
++import javax.servlet.http.HttpServlet;
++import javax.servlet.http.HttpServletRequest;
++import javax.servlet.http.HttpServletResponse;
++import javax.servlet.http.HttpSession;
++
++import static org.junit.Assert.assertEquals;
++import static org.junit.Assert.assertNotNull;
++import static org.junit.Assert.assertNull;
++import static org.junit.Assert.assertTrue;
++import static org.junit.Assert.fail;
++
++import org.junit.Test;
++
++import org.apache.catalina.Context;
++import org.apache.catalina.Host;
++import org.apache.catalina.core.StandardContext;
++import org.apache.catalina.core.StandardHost;
++import org.apache.catalina.deploy.ContextEnvironment;
++import org.apache.catalina.deploy.ContextResourceLink;
++import org.apache.catalina.ha.context.ReplicatedContext;
++import org.apache.tomcat.util.buf.ByteChunk;
++
++public class TestTomcat extends TomcatBaseTest {
++
++    /**
++     * Simple servlet to test in-line registration.
++     */
++    public static class HelloWorld extends HttpServlet {
++
++        private static final long serialVersionUID = 1L;
++
++        @Override
++        public void doGet(HttpServletRequest req, HttpServletResponse res)
++                throws IOException {
++            res.getWriter().write("Hello world");
++        }
++    }
++
++    /**
++     * Simple servlet to test the default session manager.
++     */
++    public static class HelloWorldSession extends HttpServlet {
++
++        private static final long serialVersionUID = 1L;
++
++        @Override
++        public void doGet(HttpServletRequest req, HttpServletResponse res)
++                throws IOException {
++            HttpSession s = req.getSession(true);
++            s.getId();
++            res.getWriter().write("Hello world");
++        }
++    }
++
++    /**
++     * Simple servlet to test JNDI
++     */
++    public static class HelloWorldJndi extends HttpServlet {
++
++        private static final long serialVersionUID = 1L;
++
++        private static final String JNDI_ENV_NAME = "test";
++
++        @Override
++        public void doGet(HttpServletRequest req, HttpServletResponse res)
++                throws IOException {
++
++            String name = null;
++
++            try {
++                javax.naming.Context initCtx = new InitialContext();
++                javax.naming.Context envCtx =
++                        (javax.naming.Context) 
initCtx.lookup("java:comp/env");
++                name = (String) envCtx.lookup(JNDI_ENV_NAME);
++            } catch (NamingException e) {
++                IOException ioe = new IOException(e.getMessage());
++                ioe.initCause(e);
++                throw ioe;
++            }
++
++            res.getWriter().write("Hello, " + name);
++        }
++    }
++
++    /**
++     * Servlet that tries to obtain a URL for WEB-INF/web.xml
++     */
++    public static class GetResource extends HttpServlet {
++
++        private static final long serialVersionUID = 1L;
++
++        @Override
++        public void doGet(HttpServletRequest req, HttpServletResponse res)
++        throws IOException {
++            URL url = getServletContext().getResource("/WEB-INF/web.xml");
++
++            res.getWriter().write("The URL obtained for /WEB-INF/web.xml was 
");
++            if (url == null) {
++                res.getWriter().write("null");
++            } else {
++                res.getWriter().write(url.toString() + "\n");
++                res.getWriter().write("The first 20 characters of that 
resource are:\n");
++
++                // Read some content from the resource
++                URLConnection conn = url.openConnection();
++
++                InputStream is = null;
++                Reader reader = null;
++                char cbuf[] = new char[20];
++                int read = 0;
++                try {
++                    is = conn.getInputStream();
++                    reader = new InputStreamReader(is);
++                    while (read < 20) {
++                        int len = reader.read(cbuf, read, cbuf.length - read);
++                        res.getWriter().write(cbuf, read, len);
++                        read = read + len;
++                    }
++                } finally {
++                    if (reader != null) {
++                        try { reader.close(); } catch(IOException ioe) 
{/*Ignore*/}
++                    }
++                    if (is != null) {
++                        try { is.close(); } catch(IOException ioe) 
{/*Ignore*/}
++                    }
++                }
++
++
++            }
++
++
++        }
++    }
++
++    /**
++     * Simple servlet to test initialization of servlet instances.
++     */
++    private static class InitCount extends HttpServlet {
++
++        private static final long serialVersionUID = 1L;
++
++        private AtomicInteger callCount = new AtomicInteger(0);
++
++        @Override
++        public void init() throws ServletException {
++            super.init();
++            callCount.incrementAndGet();
++        }
++
++        @Override
++        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
++                throws ServletException, IOException {
++            resp.setContentType("text/plain");
++            resp.getWriter().print("OK");
++        }
++
++        public int getCallCount() {
++            return callCount.intValue();
++        }
++    }
++
++
++//    /**
++//     * 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
++     * servlet - all programmatic, no server.xml or
++     * web.xml used.
++     *
++     * @throws Exception
++     */
++    @Test
++    public void testProgrammatic() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext("", null);
++
++        // You can customize the context by calling
++        // its API
++
++        Tomcat.addServlet(ctx, "myServlet", new HelloWorld());
++        ctx.addServletMapping("/", "myServlet");
++
++        tomcat.start();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() + "/");
++        assertEquals("Hello world", res.toString());
++    }
++
++    @Test
++    public void testSingleWebapp() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        File appDir = new File(getBuildDirectory(), "webapps/examples");
++
++        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
++
++        tomcat.start();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() +
++                "/examples/servlets/servlet/HelloWorldExample");
++        String text = res.toString();
++        assertTrue(text, text.indexOf("<h1>Hello World!</h1>") > 0);
++    }
++
++    @Test
++    public void testJsps() throws Exception {
++        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();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() +
++                "/examples/jsp/jsp2/el/basic-arithmetic.jsp");
++        String text = res.toString();
++        assertTrue(text, text.indexOf("<td>${(1==2) ? 3 : 4}</td>") > 0);
++    }
++
++    @Test
++    public void testSession() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext("", null);
++        // You can customize the context by calling
++        // its API
++
++        Tomcat.addServlet(ctx, "myServlet", new HelloWorldSession());
++        ctx.addServletMapping("/", "myServlet");
++
++        tomcat.start();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() + "/");
++        assertEquals("Hello world", res.toString());
++    }
++
++    @Test
++    public void testLaunchTime() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++        long t0 = System.currentTimeMillis();
++        tomcat.addContext(null, "", ".");
++        tomcat.start();
++        log.info("Tomcat started in [" + (System.currentTimeMillis() - t0)
++                + "] ms");
++     }
++
++
++    /**
++     * Test for enabling JNDI.
++     */
++    @Test
++    public void testEnableNaming() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext("", null);
++
++        // You can customise the context by calling its API
++
++        // Enable JNDI - it is disabled by default
++        tomcat.enableNaming();
++
++        ContextEnvironment environment = new ContextEnvironment();
++        environment.setType("java.lang.String");
++        environment.setName(HelloWorldJndi.JNDI_ENV_NAME);
++        environment.setValue("Tomcat User");
++        ctx.getNamingResources().addEnvironment(environment);
++
++        Tomcat.addServlet(ctx, "jndiServlet", new HelloWorldJndi());
++        ctx.addServletMapping("/", "jndiServlet");
++
++        tomcat.start();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() + "/");
++        assertEquals("Hello, Tomcat User", res.toString());
++    }
++
++    /**
++     * Test for enabling JNDI and using global resources.
++     */
++    @Test
++    public void testEnableNamingGlobal() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext("", null);
++
++        // You can customise the context by calling its API
++
++        // Enable JNDI - it is disabled by default
++        tomcat.enableNaming();
++
++        ContextEnvironment environment = new ContextEnvironment();
++        environment.setType("java.lang.String");
++        environment.setName("globalTest");
++        environment.setValue("Tomcat User");
++        
tomcat.getServer().getGlobalNamingResources().addEnvironment(environment);
++
++        ContextResourceLink link = new ContextResourceLink();
++        link.setGlobal("globalTest");
++        link.setName(HelloWorldJndi.JNDI_ENV_NAME);
++        ctx.getNamingResources().addResourceLink(link);
++
++        Tomcat.addServlet(ctx, "jndiServlet", new HelloWorldJndi());
++        ctx.addServletMapping("/", "jndiServlet");
++
++        tomcat.start();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() + "/");
++        assertEquals("Hello, Tomcat User", res.toString());
++    }
++
++
++    /**
++     * Test for https://bz.apache.org/bugzilla/show_bug.cgi?id=47866
++     */
++    @Test
++    public void testGetResource() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        String contextPath = "/examples";
++
++        File appDir = new File(getBuildDirectory(), "webapps" + contextPath);
++        // app dir is relative to server home
++        Context ctx =
++            tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
++
++        Tomcat.addServlet(ctx, "testGetResource", new GetResource());
++        ctx.addServletMapping("/testGetResource", "testGetResource");
++
++        tomcat.start();
++
++        ByteChunk res = new ByteChunk();
++
++        int rc =getUrl("http://localhost:"; + getPort() + contextPath +
++                "/testGetResource", res, null);
++        assertEquals(HttpServletResponse.SC_OK, rc);
++        assertTrue(res.toString().contains("<?xml version=\"1.0\" "));
++    }
++
++    @Test
++    public void testBug50826() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++        String contextPath = "/examples";
++
++        File appDir = new File(getBuildDirectory(), "webapps" + contextPath);
++        // app dir is relative to server home
++        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
++
++        Exception e = null;
++        try {
++            tomcat.destroy();
++        } catch (Exception ex) {
++            ex.printStackTrace();
++            e = ex;
++        }
++        assertNull(e);
++    }
++
++    @Test
++    public void testBug53301() throws Exception {
++        Tomcat tomcat = getTomcatInstance();
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext("", null);
++
++        InitCount initCount = new InitCount();
++        Tomcat.addServlet(ctx, "initCount", initCount);
++        ctx.addServletMapping("/", "initCount");
++
++        tomcat.start();
++
++        ByteChunk res = getUrl("http://localhost:"; + getPort() + "/");
++        assertEquals("OK", res.toString());
++
++        assertEquals(1, initCount.getCallCount());
++    }
++
++    @Test
++    public void testGetWebappConfigFileFromDirectory() {
++        Tomcat tomcat = new Tomcat();
++        
assertNotNull(tomcat.getWebappConfigFile("test/deployment/dirContext", ""));
++    }
++
++    @Test
++    public void testGetWebappConfigFileFromDirectoryNegative() {
++        Tomcat tomcat = new Tomcat();
++        assertNull(tomcat.getWebappConfigFile("test/deployment/dirNoContext", 
""));
++    }
++
++// 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 testGetDefaultContextPerAddContext() {
++        Tomcat tomcat = getTomcatInstance();
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext(null, "", null);
++        assertEquals(StandardContext.class.getName(), 
ctx.getClass().getName());
++    }
++
++    @Test
++    public void testGetBrokenContextPerAddContext() {
++        Tomcat tomcat = getTomcatInstance();
++        Host host = tomcat.getHost();
++        if (host instanceof StandardHost) {
++            ((StandardHost) host).setContextClass("InvalidContextClassName");
++        }
++
++        // No file system docBase required
++        try {
++            tomcat.addContext(null, "", null);
++            fail();
++        } catch (IllegalArgumentException e) {
++            // OK
++        }
++    }
++
++    @Test
++    public void testGetCustomContextPerAddContextWithHost() {
++        Tomcat tomcat = getTomcatInstance();
++        Host host = tomcat.getHost();
++        if (host instanceof StandardHost) {
++            ((StandardHost) host).setContextClass(ReplicatedContext.class
++                    .getName());
++        }
++
++        // No file system docBase required
++        Context ctx = tomcat.addContext(host, "", null);
++        assertEquals(ReplicatedContext.class.getName(), ctx.getClass()
++                .getName());
++    }
++
++}
+
+Property changes on: test/org/apache/catalina/startup/TestTomcat.java
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/org/apache/catalina/startup/Tomcat.java
+===================================================================
+--- test/org/apache/catalina/startup/Tomcat.java       (.../trunk)     
(revision 0)
++++ test/org/apache/catalina/startup/Tomcat.java       
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,1207 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License.  You may obtain a copy of the License at
++ * 
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ * 
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.catalina.startup;
++
++import java.io.File;
++import java.io.IOException;
++import java.lang.reflect.InvocationTargetException;
++import java.util.Stack;
++
++import javax.servlet.Servlet;
++import javax.servlet.ServletException;
++
++import org.apache.catalina.Container;
++import org.apache.catalina.Context;
++import org.apache.catalina.Engine;
++import org.apache.catalina.Globals;
++import org.apache.catalina.Host;
++import org.apache.catalina.Lifecycle;
++import org.apache.catalina.LifecycleEvent;
++import org.apache.catalina.LifecycleException;
++import org.apache.catalina.LifecycleListener;
++import org.apache.catalina.Server;
++import org.apache.catalina.Service;
++import org.apache.catalina.Wrapper;
++import org.apache.catalina.connector.Connector;
++import org.apache.catalina.core.NamingContextListener;
++import org.apache.catalina.core.StandardContext;
++import org.apache.catalina.core.StandardEngine;
++import org.apache.catalina.core.StandardHost;
++import org.apache.catalina.core.StandardServer;
++import org.apache.catalina.core.StandardService;
++import org.apache.catalina.core.StandardWrapper;
++
++// 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 
++// need for the baseDir
++
++// TODO: allow contexts without a base dir - i.e. 
++// only programmatic. This would disable the default servlet.
++
++/**
++ * Minimal tomcat starter for embedding/unit tests.
++ * 
++ * Tomcat supports multiple styles of configuration and 
++ * startup - the most common and stable is server.xml-based,
++ * implemented in org.apache.catalina.startup.Bootstrap.
++ *
++ * This class is for use in apps that embed tomcat. 
++ * Requirements:
++ * 
++ * - all tomcat classes and possibly servlets are in the classpath.
++ * ( for example all is in one big jar, or in eclipse CP, or in any other
++ * combination )
++ * 
++ * - we need one temporary directory for work files
++ * 
++ * - no config file is required. This class provides methods to 
++ * use if you have a webapp with a web.xml file, but it is 
++ * optional - you can use your own servlets.
++ * 
++ * There are a variety of 'add' methods to configure servlets and webapps. 
These
++ * methods, by default, create a simple in-memory security realm and apply it.
++ * If you need more complex security processing, you can define a subclass of
++ * this class.
++ * 
++ * This class provides a set of convenience methods for configuring webapp
++ * contexts, all overloads of the method <pre>addWebapp</pre>. These methods
++ * create a webapp context, configure it, and then add it to a {@link Host}.
++ * They do not use a global default web.xml; rather, they add a lifecycle
++ * listener that adds the standard DefaultServlet, JSP processing, and welcome
++ * files.
++ * 
++ * In complex cases, you may prefer to use the ordinary Tomcat API to create
++ * webapp contexts; for example, you might need to install a custom Loader
++ * before the call to {@link Host#addChild(Container)}. To replicate the basic
++ * behavior of the <pre>addWebapp</pre> methods, you may want to call two
++ * methods of this class: {@link #noDefaultWebXmlPath()} and
++ * {@link #getDefaultWebXmlListener()}. 
++ * 
++ * {@link #getDefaultRealm()} returns the simple security realm.
++ * 
++ * {@link #getDefaultWebXmlListener()} returns a {@link LifecycleListener} 
that
++ * adds the standard DefaultServlet, JSP processing, and welcome files. If you
++ * add this listener, you must prevent Tomcat from applying any standard 
global
++ * web.xml with ...
++ * 
++ * {@link #noDefaultWebXmlPath()} returns a dummy pathname to configure to
++ * prevent {@link ContextConfig} from trying to apply a global web.xml file. 
++ * 
++ * This class provides a main() and few simple CLI arguments,
++ * see setters for doc. It can be used for simple tests and
++ * demo.
++ * 
++ * @see <a 
href="http://svn.apache.org/repos/asf/tomcat/trunk/test/org/apache/catalina/startup/TestTomcat.java";>TestTomcat</a>
++ * @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>();
++
++    // Single engine, service, server, connector - few cases need more,
++    // they can use server.xml
++    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;
++
++    // TODO: it's easy to add support for more hosts - but is it 
++    // really needed ?
++
++    // TODO: allow use of in-memory connector
++
++    protected int port = 8080;
++    protected String hostname = "localhost";
++    protected String basedir;
++
++    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. 
++     * 
++     * By default, if this method is not called, we use:
++     *  - system properties - catalina.base, catalina.home 
++     *  - $HOME/tomcat.$PORT
++     * ( /tmp doesn't seem a good choice for security ).
++     *   
++     *
++     * TODO: better default ? Maybe current dir ? 
++     * TODO: disable work dir if not needed ( no jsp, etc ).
++     */
++    public void setBaseDir(String basedir) {
++        this.basedir = basedir;
++    }
++
++    /** 
++     * Set the port for the default connector. Must 
++     * be called before start().
++     */
++    public void setPort(int port) {
++        this.port = port;
++    }
++
++    /** 
++     * The the hostname of the default host, default is 
++     * 'localhost'.
++     */
++    public void setHostname(String s) {
++        hostname = s;
++    }
++
++    /**
++     * This is equivalent to adding a web application to Tomcat&apos;s webapps
++     * directory. The equivalent of the default web.xml will be applied  to 
the
++     * web application and any WEB-INF/web.xml and META-INF/context.xml 
packaged
++     * with the application will be processed normally. Normal web fragment 
and
++     * {@link javax.servlet.ServletContainerInitializer} processing will be
++     * applied.
++     *
++     * @throws ServletException
++     */
++    public Context addWebapp(String contextPath, String docBase) throws 
ServletException {
++        return addWebapp(getHost(), contextPath, docBase);
++    }
++
++
++    /** 
++     * Add a context - programmatic mode, no web.xml used.
++     *
++     * API calls equivalent with web.xml:
++     * 
++     * context-param
++     *  ctx.addParameter("name", "value");
++     *     
++     *
++     * error-page
++     *    ErrorPage ep = new ErrorPage();
++     *    ep.setErrorCode(500);
++     *    ep.setLocation("/error.html");
++     *    ctx.addErrorPage(ep);
++     *   
++     * ctx.addMimeMapping("ext", "type");
++     * 
++     * Note: If you reload the Context, all your configuration will be lost. 
If
++     * you need reload support, consider using a LifecycleListener to provide
++     * your configuration.
++     *  
++     * TODO: add the rest
++     *
++     *  @param contextPath "" for root context.
++     *  @param docBase base dir for the context, for static files. Must exist,
++     *  relative to the server home
++     */
++    public Context addContext(String contextPath, String docBase) {
++        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);
++//    }
++
++    /**
++     * Static version of {@link #addServlet(String, String, String)}
++     * @param ctx           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 static Wrapper addServlet(Context ctx, 
++                                      String servletName, 
++                                      String servletClass) {
++        // will do class for name and set init params
++        Wrapper sw = ctx.createWrapper();
++        sw.setServletClass(servletClass);
++        sw.setName(servletName);
++        ctx.addChild(sw);
++        
++        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);
++//    }
++
++    /**
++     * Static version of {@link #addServlet(String, String, Servlet)}.
++     * @param ctx           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 static Wrapper addServlet(Context ctx,
++                                      String servletName, 
++                                      Servlet servlet) {
++        // will do class for name and set init params
++        Wrapper sw = new ExistingStandardWrapper(servlet);
++        sw.setName(servletName);
++        ctx.addChild(sw);
++        
++        return sw;
++    }
++    
++
++    /**
++     * Initialise the server.
++     * 
++     * @throws LifecycleException
++     */
++    public void init() throws LifecycleException {
++        getServer();
++        getConnector();
++        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 {
++        if (!started) {
++            init();
++            started = true;
++            server.start();
++        }
++    }
++
++    /** 
++     * Stop the server.
++     * 
++     * @throws LifecycleException 
++     */
++    public void stop() throws LifecycleException {
++        if (started) {
++            started = false;
++            server.stop();
++        }
++    }
++
++
++    /**
++     * Destroy the server. This object cannot be used once this method has 
been
++     * called.
++     */
++    public void destroy() throws LifecycleException {
++        if (initialized) {
++            stop();
++            initialized = false;
++            // 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);
++//        }
++//        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.
++     * 
++     * Alternatively, you can construct a Connector and set any params,
++     * then call addConnector(Connector)
++     * 
++     * @return A connector object that can be customized
++     */
++    public Connector getConnector() {
++        getServer();
++        if (connector != null) {
++            return connector;
++        }
++
++        // The same as in standard Tomcat configuration.
++        // 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).
++        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.
++     */
++    public Service getService() {
++        getServer();
++        return service;
++    }
++
++    /** 
++     * Sets the current host - all future webapps will
++     * be added to this host. When tomcat starts, the 
++     * host will be the default host.
++     * 
++     * @param host
++     */
++    public void setHost(Host host) {
++        this.host = host;
++    }
++
++    public Host getHost() {
++        if (host == null) {
++            host = new StandardHost();
++            host.setName(hostname);
++
++            getEngine().addChild( host );
++        }
++        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;
++//    }
++//    
++
++    /** 
++     * Access to the engine, for further customization.
++     */
++    public Engine getEngine() {
++        if(engine == null ) {
++            getServer();
++            engine = new StandardEngine();
++            engine.setName( "Tomcat" );
++            engine.setDefaultHost(hostname);
++            // @Deprecated
++            // if (defaultRealm == null) {
++            //    initSimpleAuth();
++            // }
++            // engine.setRealm(defaultRealm);
++            service.setContainer(engine);
++        }
++        return engine;
++    }
++
++    /**
++     * Get the server object. You can add listeners and few more
++     * customizations. JNDI is disabled by default.  
++     */
++    public Server getServer() {
++
++        if (server != null) {
++            return server;
++        }
++
++        initBaseDir();
++
++        System.setProperty("catalina.useNaming", "false");
++
++        server = new StandardServer();
++        server.setPort(-1);
++
++        service = new StandardService();
++        service.setName("Tomcat");
++        server.addService(service);
++        return server;
++    }
++
++    public Context addContext(Host host, String contextPath, String dir) {
++        return addContext(host, contextPath, contextPath, dir);
++    }
++
++    private Context addContext(Host host, String contextPath, String 
contextName,
++            String dir) {
++//        silence(host, contextPath);
++        Context ctx = createContext(host, contextPath);
++        ctx.setName(contextName);
++        ctx.setPath(contextPath);
++        ctx.setDocBase(dir);
++        ((Lifecycle) ctx).addLifecycleListener(new FixContextListener());
++
++        if (host == null) {
++            getHost().addChild(ctx);
++        } else {
++            host.addChild(ctx);
++        }
++        return ctx;
++    }
++    
++    public Context addWebapp(Host host, String contextPath, String docBase) {
++        return addWebapp(host, contextPath, contextPath, docBase);
++    }
++
++    /**
++     * @see #addWebapp(String, String)
++     *
++     * @param name Ignored. The contextPath will be used
++     *
++     * @deprecated Use {@link #addWebapp(Host, String, String)}
++     */
++    @Deprecated
++    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);
++
++        ((Lifecycle) ctx).addLifecycleListener(new DefaultWebXmlListener());
++        ctx.setConfigFile(getWebappConfigFile(docBase, contextPath));
++
++        ContextConfig ctxCfg = new ContextConfig();
++        ((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);
++        } else {
++            host.addChild(ctx);
++        }
++
++        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;
++//    }
++//
++//
++//    // ---------- 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) {
++            basedir = System.getProperty(Globals.CATALINA_BASE_PROP);
++        }
++        if (basedir == null) {
++            basedir = catalinaHome;
++        }
++        if (basedir == null) {
++            // Create a temp dir.
++            basedir = System.getProperty("user.dir") + "/tomcat." + port;
++            File home = new File(basedir);
++            home.mkdir();
++            if (!home.isAbsolute()) {
++                try {
++                    basedir = home.getCanonicalPath();
++                } catch (IOException e) {
++                    basedir = home.getAbsolutePath();
++                }
++            }
++        }
++        if (catalinaHome == null) {
++            System.setProperty(Globals.CATALINA_HOME_PROP, basedir);
++        }
++        System.setProperty(Globals.CATALINA_BASE_PROP, basedir);
++    }
++
++// 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>.
++     * The default constructor of the class that was configured with
++     * {@link StandardHost#setContextClass(String)} will be used
++     *
++     * @param host
++     *            host for which the {@link Context} should be created, or
++     *            <code>null</code> if default host should be used
++     * @param url
++     *            path of the webapp which should get the {@link Context}
++     * @return newly created {@link Context}
++     */
++    private Context createContext(Host host, String url) {
++        String contextClass = StandardContext.class.getName();
++        if (host == null) {
++            host = this.getHost();
++        }
++        if (host instanceof StandardHost) {
++            contextClass = ((StandardHost) host).getContextClass();
++        }
++        try {
++            return (Context) Class.forName(contextClass).getConstructor()
++                    .newInstance();
++        } catch (InstantiationException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        } catch (IllegalAccessException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        } catch (IllegalArgumentException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        } catch (InvocationTargetException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        } catch (NoSuchMethodException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        } catch (SecurityException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        } catch (ClassNotFoundException e) {
++            throw new IllegalArgumentException(
++                    "Can't instantiate context-class " + contextClass
++                            + " for host " + host + " and url "
++                            + url, e);
++        }
++    }
++
++    /**
++     * Enables JNDI naming which is disabled by default. Server must implement
++     * {@link Lifecycle} in order for the {@link NamingContextListener} to be
++     * used.
++     * 
++     */
++    public void enableNaming() {
++        // Make sure getServer() has been called as that is where naming is
++        // disabled
++        getServer();
++        server.addLifecycleListener(new NamingContextListener());
++
++        System.setProperty("catalina.useNaming", "true");
++
++        String value = "org.apache.naming";
++        String oldValue =
++            System.getProperty(javax.naming.Context.URL_PKG_PREFIXES);
++        if (oldValue != null) {
++            if (oldValue.contains(value)) {
++                value = oldValue;
++            } else {
++                value = value + ":" + oldValue;
++            }
++        }
++        System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, value);
++
++        value = System.getProperty
++            (javax.naming.Context.INITIAL_CONTEXT_FACTORY);
++        if (value == null) {
++            System.setProperty
++                (javax.naming.Context.INITIAL_CONTEXT_FACTORY,
++                 "org.apache.naming.java.javaURLContextFactory");
++        }
++    }
++
++//    /**
++//     * 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)}
++     * @param ctx   The context to set the defaults for
++     */
++    public static void initWebappDefaults(Context ctx) {
++        // Default servlet 
++        Wrapper servlet = addServlet(
++                ctx, "default", 
"org.apache.catalina.servlets.DefaultServlet");
++        servlet.setLoadOnStartup(1);
++        //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 mappings
++        ctx.addServletMapping("/", "default");
++        ctx.addServletMapping("*.jsp", "jsp");
++        ctx.addServletMapping("*.jspx", "jsp");
++
++        // Sessions
++        ctx.setSessionTimeout(30);
++        
++        // MIME mappings
++        for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length;) {
++            ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++],
++                    DEFAULT_MIME_MAPPINGS[i++]);
++        }
++        
++        // Welcome files
++        ctx.addWelcomeFile("index.html");
++        ctx.addWelcomeFile("index.htm");
++        ctx.addWelcomeFile("index.jsp");
++    }
++
++    
++    /**
++     * Fix startup sequence - required if you don't use web.xml.
++     * 
++     * The start() method in context will set 'configured' to false - and
++     * expects a listener to set it back to true.
++     */
++    public static class FixContextListener implements LifecycleListener {
++
++        public void lifecycleEvent(LifecycleEvent event) {
++            try {
++                Context context = (Context) event.getLifecycle();
++                // Using START_EVENT, Tomcat 7+ uses CONFIGURE_START_EVENT 
here.
++                if (event.getType().equals(Lifecycle.START_EVENT)) {
++                    context.setConfigured(true);
++                }
++// 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;
++            }
++        }
++        
++    }
++
++
++    /**
++     * Fix reload - required if reloading and using programmatic 
configuration.
++     * When a context is reloaded, any programmatic configuration is lost. 
This
++     * listener sets the equivalent of conf/web.xml when the context starts.
++     */
++    public static class DefaultWebXmlListener implements LifecycleListener {
++        public void lifecycleEvent(LifecycleEvent event) {
++            if (Lifecycle.BEFORE_START_EVENT.equals(event.getType())) {
++                initWebappDefaults((Context) event.getLifecycle());
++            }
++        }
++    }
++
++
++    /**
++     * Helper class for wrapping existing servlets. This disables servlet 
++     * lifecycle and normal reloading, but also reduces overhead and provide
++     * more direct control over the servlet.  
++     */
++    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 ) {
++            this.existing = existing;
++            if (existing instanceof javax.servlet.SingleThreadModel) {
++                singleThreadModel = true;
++                instancePool = new Stack<Servlet>();
++            }
++        }
++        @Override
++        public synchronized Servlet loadServlet() throws ServletException {
++            if (singleThreadModel) {
++                Servlet instance;
++                try {
++                    instance = existing.getClass().newInstance();
++                } catch (InstantiationException e) {
++                    throw new ServletException(e);
++                } catch (IllegalAccessException e) {
++                    throw new ServletException(e);
++                }
++                instance.init(facade);
++                return instance;
++            } else {
++                if (!instanceInitialized) {
++                    existing.init(facade);
++                    instanceInitialized = true;
++                }
++                return existing;
++            }
++        }
++        @Override
++        public long getAvailable() {
++            return 0;
++        }
++        @Override
++        public boolean isUnavailable() {
++            return false;       
++        }
++        @Override
++        public Servlet getServlet() {
++            return existing;
++        }
++        @Override
++        public String getServletClass() {
++            return existing.getClass().getName();
++        }
++    }
++    
++    /**
++     * TODO: would a properties resource be better ? Or just parsing
++     * /etc/mime.types ?
++     * This is needed because we don't use the default web.xml, where this 
++     * is encoded.
++     */
++    private static final String[] DEFAULT_MIME_MAPPINGS = {
++        "abs", "audio/x-mpeg",
++        "ai", "application/postscript",
++        "aif", "audio/x-aiff",
++        "aifc", "audio/x-aiff",
++        "aiff", "audio/x-aiff",
++        "aim", "application/x-aim",
++        "art", "image/x-jg",
++        "asf", "video/x-ms-asf",
++        "asx", "video/x-ms-asf",
++        "au", "audio/basic",
++        "avi", "video/x-msvideo",
++        "avx", "video/x-rad-screenplay",
++        "bcpio", "application/x-bcpio",
++        "bin", "application/octet-stream",
++        "bmp", "image/bmp",
++        "body", "text/html",
++        "cdf", "application/x-cdf",
++        "cer", "application/pkix-cert",
++        "class", "application/java",
++        "cpio", "application/x-cpio",
++        "csh", "application/x-csh",
++        "css", "text/css",
++        "dib", "image/bmp",
++        "doc", "application/msword",
++        "dtd", "application/xml-dtd",
++        "dv", "video/x-dv",
++        "dvi", "application/x-dvi",
++        "eps", "application/postscript",
++        "etx", "text/x-setext",
++        "exe", "application/octet-stream",
++        "gif", "image/gif",
++        "gtar", "application/x-gtar",
++        "gz", "application/x-gzip",
++        "hdf", "application/x-hdf",
++        "hqx", "application/mac-binhex40",
++        "htc", "text/x-component",
++        "htm", "text/html",
++        "html", "text/html",
++        "ief", "image/ief",
++        "jad", "text/vnd.sun.j2me.app-descriptor",
++        "jar", "application/java-archive",
++        "java", "text/x-java-source",
++        "jnlp", "application/x-java-jnlp-file",
++        "jpe", "image/jpeg",
++        "jpeg", "image/jpeg",
++        "jpg", "image/jpeg",
++        "js", "application/javascript",
++        "jsf", "text/plain",
++        "jspf", "text/plain",
++        "kar", "audio/midi",
++        "latex", "application/x-latex",
++        "m3u", "audio/x-mpegurl",
++        "mac", "image/x-macpaint",
++        "man", "text/troff",
++        "mathml", "application/mathml+xml",
++        "me", "text/troff",
++        "mid", "audio/midi",
++        "midi", "audio/midi",
++        "mif", "application/x-mif",
++        "mov", "video/quicktime",
++        "movie", "video/x-sgi-movie",
++        "mp1", "audio/mpeg",
++        "mp2", "audio/mpeg",
++        "mp3", "audio/mpeg",
++        "mp4", "video/mp4",
++        "mpa", "audio/mpeg",
++        "mpe", "video/mpeg",
++        "mpeg", "video/mpeg",
++        "mpega", "audio/x-mpeg",
++        "mpg", "video/mpeg",
++        "mpv2", "video/mpeg2",
++        "nc", "application/x-netcdf",
++        "oda", "application/oda",
++        "odb", "application/vnd.oasis.opendocument.database",
++        "odc", "application/vnd.oasis.opendocument.chart",
++        "odf", "application/vnd.oasis.opendocument.formula",
++        "odg", "application/vnd.oasis.opendocument.graphics",
++        "odi", "application/vnd.oasis.opendocument.image",
++        "odm", "application/vnd.oasis.opendocument.text-master",
++        "odp", "application/vnd.oasis.opendocument.presentation",
++        "ods", "application/vnd.oasis.opendocument.spreadsheet",
++        "odt", "application/vnd.oasis.opendocument.text",
++        "otg", "application/vnd.oasis.opendocument.graphics-template",
++        "oth", "application/vnd.oasis.opendocument.text-web",
++        "otp", "application/vnd.oasis.opendocument.presentation-template",
++        "ots", "application/vnd.oasis.opendocument.spreadsheet-template ",
++        "ott", "application/vnd.oasis.opendocument.text-template",
++        "ogx", "application/ogg",
++        "ogv", "video/ogg",
++        "oga", "audio/ogg",
++        "ogg", "audio/ogg",
++        "spx", "audio/ogg",
++        "flac", "audio/flac",
++        "anx", "application/annodex",
++        "axa", "audio/annodex",
++        "axv", "video/annodex",
++        "xspf", "application/xspf+xml",
++        "pbm", "image/x-portable-bitmap",
++        "pct", "image/pict",
++        "pdf", "application/pdf",
++        "pgm", "image/x-portable-graymap",
++        "pic", "image/pict",
++        "pict", "image/pict",
++        "pls", "audio/x-scpls",
++        "png", "image/png",
++        "pnm", "image/x-portable-anymap",
++        "pnt", "image/x-macpaint",
++        "ppm", "image/x-portable-pixmap",
++        "ppt", "application/vnd.ms-powerpoint",
++        "pps", "application/vnd.ms-powerpoint",
++        "ps", "application/postscript",
++        "psd", "image/vnd.adobe.photoshop",
++        "qt", "video/quicktime",
++        "qti", "image/x-quicktime",
++        "qtif", "image/x-quicktime",
++        "ras", "image/x-cmu-raster",
++        "rdf", "application/rdf+xml",
++        "rgb", "image/x-rgb",
++        "rm", "application/vnd.rn-realmedia",
++        "roff", "text/troff",
++        "rtf", "application/rtf",
++        "rtx", "text/richtext",
++        "sh", "application/x-sh",
++        "shar", "application/x-shar",
++        /*"shtml", "text/x-server-parsed-html",*/
++        "sit", "application/x-stuffit",
++        "snd", "audio/basic",
++        "src", "application/x-wais-source",
++        "sv4cpio", "application/x-sv4cpio",
++        "sv4crc", "application/x-sv4crc",
++        "svg", "image/svg+xml",
++        "svgz", "image/svg+xml",
++        "swf", "application/x-shockwave-flash",
++        "t", "text/troff",
++        "tar", "application/x-tar",
++        "tcl", "application/x-tcl",
++        "tex", "application/x-tex",
++        "texi", "application/x-texinfo",
++        "texinfo", "application/x-texinfo",
++        "tif", "image/tiff",
++        "tiff", "image/tiff",
++        "tr", "text/troff",
++        "tsv", "text/tab-separated-values",
++        "txt", "text/plain",
++        "ulw", "audio/basic",
++        "ustar", "application/x-ustar",
++        "vxml", "application/voicexml+xml",
++        "xbm", "image/x-xbitmap",
++        "xht", "application/xhtml+xml",
++        "xhtml", "application/xhtml+xml",
++        "xls", "application/vnd.ms-excel",
++        "xml", "application/xml",
++        "xpm", "image/x-xpixmap",
++        "xsl", "application/xml",
++        "xslt", "application/xslt+xml",
++        "xul", "application/vnd.mozilla.xul+xml",
++        "xwd", "image/x-xwindowdump",
++        "vsd", "application/vnd.visio",
++        "wav", "audio/x-wav",
++        "wbmp", "image/vnd.wap.wbmp",
++        "wml", "text/vnd.wap.wml",
++        "wmlc", "application/vnd.wap.wmlc",
++        "wmls", "text/vnd.wap.wmlsc",
++        "wmlscriptc", "application/vnd.wap.wmlscriptc",
++        "wmv", "video/x-ms-wmv",
++        "wrl", "model/vrml",
++        "wspolicy", "application/wspolicy+xml",
++        "Z", "application/x-compress",
++        "z", "application/x-compress",
++        "zip", "application/zip"
++    };
++
++    protected String getWebappConfigFile(String path, 
@SuppressWarnings("unused") String contextPath) {
++        File docBase = new File(path);
++        if (docBase.isDirectory()) {
++            return getWebappConfigFileFromDirectory(docBase);
++        } else {
++            // 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 String getWebappConfigFileFromDirectory(File docBase) {
++        String result = null;
++        File webAppContextXml = new File(docBase, 
Constants.ApplicationContextXml);
++        if (webAppContextXml.exists()) {
++            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;
++//    }
++}
+
+Property changes on: test/org/apache/catalina/startup/Tomcat.java
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/org/apache/catalina/startup/FastNonSecureRandom.java
+===================================================================
+--- test/org/apache/catalina/startup/FastNonSecureRandom.java  (.../trunk)     
(revision 0)
++++ test/org/apache/catalina/startup/FastNonSecureRandom.java  
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,60 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.catalina.startup;
++
++import java.security.SecureRandom;
++import java.util.Random;
++
++public class FastNonSecureRandom extends SecureRandom {
++
++    private static final long serialVersionUID = 1L;
++
++    private final Random random = new Random();
++
++    @Override
++    public String getAlgorithm() {
++        return "INSECURE";
++    }
++
++    @Override
++    public synchronized void setSeed(byte[] seed) {
++        // Not implemented
++    }
++
++    @Override
++    public synchronized void setSeed(long seed) {
++        // The super class constructor calls this method earlier than our
++        // fields are initialized. Ignore the call.
++        if (random == null) {
++            return;
++        }
++        random.setSeed(seed);
++    }
++
++    @Override
++    public synchronized void nextBytes(byte[] bytes) {
++        random.nextBytes(bytes);
++    }
++
++    @Override
++    public byte[] generateSeed(int numBytes) {
++        byte[] value = new byte[numBytes];
++        nextBytes(value);
++        return value;
++    }
++
++}
+\ No newline at end of file
+
+Property changes on: test/org/apache/catalina/startup/FastNonSecureRandom.java
+___________________________________________________________________
+Added: svn:eol-style
+## -0,0 +1 ##
++native
+\ No newline at end of property
+Index: test/org/apache/catalina/startup/TomcatBaseTest.java
+===================================================================
+--- test/org/apache/catalina/startup/TomcatBaseTest.java       (.../trunk)     
(revision 0)
++++ test/org/apache/catalina/startup/TomcatBaseTest.java       
(.../branches/tomcat6-testing_20160106) (revision 1726111)
+@@ -0,0 +1,796 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.catalina.startup;
++
++import java.io.BufferedInputStream;
++import java.io.File;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.OutputStream;
++import java.io.PrintWriter;
++import java.net.HttpURLConnection;
++import java.net.InetAddress;
++import java.net.URL;
++import java.util.Enumeration;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Map;
++
++import javax.servlet.ServletContext;
++import javax.servlet.ServletException;
++import javax.servlet.http.HttpServlet;
++import javax.servlet.http.HttpServletRequest;
++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;
++import org.junit.Assert;
++import org.junit.Before;
++
++import org.apache.catalina.Container;
++import org.apache.catalina.LifecycleException;
++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;
++import org.apache.catalina.core.StandardServer;
++import org.apache.catalina.session.ManagerBase;
++import org.apache.catalina.session.StandardManager;
++import org.apache.catalina.valves.AccessLogValve;
++import org.apache.tomcat.util.buf.ByteChunk;
++
++/**
++ * Base test case that provides a Tomcat instance for each test - mainly so we
++ * don't have to keep writing the cleanup code.
++ */
++public abstract class TomcatBaseTest extends LoggingBaseTest {
++    private Tomcat tomcat;
++    private boolean accessLogEnabled = false;
++
++    public static final String TEMP_DIR = 
System.getProperty("java.io.tmpdir");
++
++    /**
++     * Make Tomcat instance accessible to sub-classes.
++     */
++    public Tomcat getTomcatInstance() {
++        return tomcat;
++    }
++
++    /**
++     * Sub-classes need to know port so they can connect
++     */
++    public int getPort() {
++        return tomcat.getConnector().getLocalPort();
++    }
++
++    /**
++     * Sub-classes may want to check, whether an AccessLogValve is active
++     */
++    public boolean isAccessLogEnabled() {
++        return accessLogEnabled;
++    }
++
++    @Before
++    @Override
++    public void setUp() throws Exception {
++        super.setUp();
++
++        // Trigger loading of catalina.properties
++        CatalinaProperties.getProperty("foo");
++
++        File appBase = new File(getTemporaryDirectory(), "webapps");
++        if (!appBase.exists() && !appBase.mkdir()) {
++            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();
++        Connector connector = new Connector(protocol);
++        // Listen only on localhost
++        connector.setAttribute("address",
++                InetAddress.getByName("localhost").getHostAddress());
++        // Use random free port
++        connector.setPort(0);
++        // Mainly set to reduce timeouts during async tests
++        connector.setAttribute("connectionTimeout", "3000");
++        tomcat.getService().addConnector(connector);
++        tomcat.setConnector(connector);
++
++        // Add AprLifecycleListener if we are using the Apr connector
++        if (protocol.contains("Apr")) {
++            StandardServer server = (StandardServer) tomcat.getServer();
++            AprLifecycleListener listener = new AprLifecycleListener();
++            listener.setSSLRandomSeed("/dev/urandom");
++            server.addLifecycleListener(listener);
++            connector.setAttribute("pollerThreadCount", Integer.valueOf(1));
++        }
++
++        File catalinaBase = getTemporaryDirectory();
++        tomcat.setBaseDir(catalinaBase.getAbsolutePath());
++        tomcat.getHost().setAppBase(appBase.getAbsolutePath());
++
++        accessLogEnabled = Boolean.parseBoolean(
++            System.getProperty("tomcat.test.accesslog", "false"));
++        if (accessLogEnabled) {
++            String accessLogDirectory = System
++                    .getProperty("tomcat.test.reports");
++            if (accessLogDirectory == null) {
++                accessLogDirectory = new File(getBuildDirectory(), "logs")
++                        .toString();
++            }
++            AccessLogValve alv = new AccessLogValve();
++            alv.setDirectory(accessLogDirectory);
++            alv.setPattern("%h %l %u %t \"%r\" %s %b %I %D");
++            tomcat.getHost().getPipeline().addValve(alv);
++        }
++
++        // Cannot delete the whole tempDir, because logs are there,
++        // but delete known subdirectories of it.
++        addDeleteOnTearDown(new File(catalinaBase, "webapps"));
++        addDeleteOnTearDown(new File(catalinaBase, "work"));
++    }
++
++    protected String getProtocol() {
++        // Has a protocol been specified
++        String protocol = System.getProperty("tomcat.test.protocol");
++
++        // Use BIO by default
++        if (protocol == null) {
++            protocol = "org.apache.coyote.http11.Http11Protocol";
++        }
++
++        return protocol;
++    }
++
++    @After
++    @Override
++    public void tearDown() throws Exception {
++        try {
++            if (tomcat.server != null) {
++                tomcat.stop();
++                tomcat.destroy();
++            }
++        } finally {
++            ServerFactory.clear();
++            super.tearDown();
++        }
++    }
++
++    /**
++     * Simple Hello World servlet for use by test cases
++     */
++    public static final class HelloWorldServlet extends HttpServlet {
++
++        private static final long serialVersionUID = 1L;
++
++        public static final String RESPONSE_TEXT =
++            "<html><body><p>Hello World</p></body></html>";
++
++        @Override
++        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
++                throws ServletException, IOException {
++            PrintWriter out = resp.getWriter();
++            out.print(RESPONSE_TEXT);
++        }
++    }
++
++
++    public static final class RequestDescriptor {
++
++        private final Map<String, String> requestInfo =
++            new HashMap<String, String>();
++        private final Map<String, String> contextInitParameters =
++            new HashMap<String, String>();
++        private final Map<String, String> contextAttributes =
++            new HashMap<String, String>();
++        private final Map<String, String> headers =
++            new CaseInsensitiveKeyMap<String>();
++        private final Map<String, String> attributes =
++            new HashMap<String, String>();
++        private final Map<String, String> params =
++            new HashMap<String, String>();
++        private final Map<String, String> sessionAttributes =
++            new HashMap<String, String>();
++
++        public Map<String, String> getRequestInfo() {
++            return requestInfo;
++        }
++
++        public Map<String, String> getContextInitParameters() {
++            return contextInitParameters;
++        }
++
++        public Map<String, String> getContextAttributes() {
++            return contextAttributes;
++        }
++
++        public Map<String, String> getHeaders() {
++            return headers;
++        }
++
++        public Map<String, String> getAttributes() {
++            return attributes;
++        }
++
++        public Map<String, String> getParams() {
++            return params;
++        }
++
++        public Map<String, String> getSessionAttributes() {
++            return sessionAttributes;
++        }
++
++        public String getRequestInfo(String name) {
++            return requestInfo.get(name);
++        }
++
++        public void putRequestInfo(String name, String value) {
++            requestInfo.put(name, value);
++        }
++
++        public String getContextInitParameter(String name) {
++            return contextInitParameters.get(name);
++        }
++
++        public void putContextInitParameter(String name, String value) {
++            contextInitParameters.put(name, value);
++        }
++
++        public String getContextAttribute(String name) {
++            return contextAttributes.get(name);
++        }
++
++        public void putContextAttribute(String name, String value) {
++            contextAttributes.put(name, value);
++        }
++
++        public String getHeader(String name) {
++            return headers.get(name);
++        }
++
++        public void putHeader(String name, String value) {
++            headers.put(name, value);
++        }
++
++        public String getAttribute(String name) {
++            return attributes.get(name);
++        }
++
++        public void putAttribute(String name, String value) {
++            attributes.put(name, value);

[... 1503 lines stripped ...]



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to