Author: kkolinko Date: Tue Aug 26 11:50:42 2014 New Revision: 1620577 URL: http://svn.apache.org/r1620577 Log: For https://issues.apache.org/bugzilla/show_bug.cgi?id=56882 Add testcase for processing of forwards and includes when Context have been reloaded. The bug is absent in Tomcat 7.
This is a backport of r1620326. Modified: tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapperWebapps.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/one.jsp tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/two.html tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/foo.jsp tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/include.jsp Modified: tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapper.java Tue Aug 26 11:50:42 2014 @@ -17,11 +17,13 @@ package org.apache.tomcat.util.http.mapper; import java.util.Arrays; +import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -34,6 +36,8 @@ import org.apache.tomcat.util.buf.Messag public class TestMapper extends LoggingBaseTest { private Mapper mapper; + private Mapper mapperForContext1; + private Mapper mapperForContext2; @Before @Override @@ -71,11 +75,11 @@ public class TestMapper extends LoggingB mapper.addContextVersion("iowejoiejfoiew", "blah7", "/foo/bar", "0", "context2", welcomes, null, null); - mapper.addWrappers( - "iowejoiejfoiew", - "/foo/bar", - "0", - Arrays.asList(new WrapperMappingInfo[] { + Collection<WrapperMappingInfo> wrappersForContext1 = Arrays + .asList(new WrapperMappingInfo[] { new WrapperMappingInfo("/", + "context1-defaultWrapper", false, false) }); + Collection<WrapperMappingInfo> wrappersForContext2 = Arrays + .asList(new WrapperMappingInfo[] { new WrapperMappingInfo("/fo/*", "wrapper0", false, false), new WrapperMappingInfo("/", "wrapper1", false, false), @@ -87,7 +91,26 @@ public class TestMapper extends LoggingB new WrapperMappingInfo("/blah/bobou/*", "wrapper5", false, false), new WrapperMappingInfo("*.htm", "wrapper6", false, - false) })); + false) }); + + mapper.addWrappers("iowejoiejfoiew", "/foo", "0", wrappersForContext1); + mapperForContext1 = new Mapper(); + mapperForContext1.setContext("/foo", new String[0], null); + for (WrapperMappingInfo wrapper : wrappersForContext1) { + mapperForContext1.addWrapper(wrapper.getMapping(), + wrapper.getWrapper(), wrapper.isJspWildCard(), + wrapper.isResourceOnly()); + } + + mapper.addWrappers("iowejoiejfoiew", "/foo/bar", "0", + wrappersForContext2); + mapperForContext2 = new Mapper(); + mapperForContext2.setContext("/foo/bar", new String[0], null); + for (WrapperMappingInfo wrapper : wrappersForContext2) { + mapperForContext2.addWrapper(wrapper.getMapping(), + wrapper.getWrapper(), wrapper.isJspWildCard(), + wrapper.isResourceOnly()); + } mapper.addContextVersion( "iowejoiejfoiew", @@ -269,11 +292,20 @@ public class TestMapper extends LoggingB assertEquals(1, mappedContext.versions.length); assertEquals("0", mappedContext.versions[0].name); Object oldHost = mappedHost.object; + Object oldContext = mappedContext.versions[0].object; + assertEquals("context2", oldContext.toString()); + + Object oldContext1 = mappedHost.contextList.contexts[contextPos - 1].versions[0].object; + assertEquals("context1", oldContext1.toString()); mappingData.recycle(); mapper.map(hostMB, uriMB, null, mappingData); assertEquals("blah7", mappingData.host.toString()); assertEquals("context2", mappingData.context.toString()); + assertEquals("wrapper5", mappingData.wrapper.toString()); + mappingData.recycle(); + mapperForContext2.map(uriMB, mappingData); + assertEquals("wrapper5", mappingData.wrapper.toString()); Object newContext = "newContext"; mapper.addContextVersion( @@ -285,7 +317,7 @@ public class TestMapper extends LoggingB null, null, Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo( - "/", "default", false, false) })); + "/", "newContext-default", false, false) })); assertEquals(2, mappedContext.versions.length); assertEquals("0", mappedContext.versions[0].name); @@ -293,6 +325,7 @@ public class TestMapper extends LoggingB mappingData.recycle(); mapper.map(hostMB, uriMB, null, mappingData); assertEquals("newContext", mappingData.context.toString()); + assertEquals("newContext-default", mappingData.wrapper.toString()); mapper.removeContextVersion(hostName, contextPath, "0"); @@ -301,6 +334,7 @@ public class TestMapper extends LoggingB mappingData.recycle(); mapper.map(hostMB, uriMB, null, mappingData); assertEquals("newContext", mappingData.context.toString()); + assertEquals("newContext-default", mappingData.wrapper.toString()); mapper.removeContextVersion(hostName, contextPath, "1"); @@ -309,6 +343,10 @@ public class TestMapper extends LoggingB mappingData.recycle(); mapper.map(hostMB, uriMB, null, mappingData); assertEquals("context1", mappingData.context.toString()); + assertEquals("context1-defaultWrapper", mappingData.wrapper.toString()); + mappingData.recycle(); + mapperForContext1.map(uriMB, mappingData); + assertEquals("context1-defaultWrapper", mappingData.wrapper.toString()); mapper.addContextVersion( hostName, @@ -319,7 +357,7 @@ public class TestMapper extends LoggingB null, null, Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo( - "/", "default", false, false) })); + "/", "newContext-defaultWrapper2", false, false) })); mappedContext = mappedHost.contextList.contexts[contextPos]; assertEquals(contextPath, mappedContext.name); @@ -328,6 +366,79 @@ public class TestMapper extends LoggingB mappingData.recycle(); mapper.map(hostMB, uriMB, null, mappingData); assertEquals("newContext", mappingData.context.toString()); + assertEquals("newContext-defaultWrapper2", mappingData.wrapper.toString()); + } + + @Test + public void testReloadContextVersion() throws Exception { + final String hostName = "iowejoiejfoiew"; + final int iowPos = 3; + final String contextPath = "/foo/bar"; + final int contextPos = 2; + + MappingData mappingData = new MappingData(); + MessageBytes hostMB = MessageBytes.newInstance(); + MessageBytes uriMB = MessageBytes.newInstance(); + hostMB.setString(hostName); + uriMB.setString("/foo/bar/blah/bobou/foo"); + + // Verifying configuration created by setUp() + Mapper.Host mappedHost = mapper.hosts[iowPos]; + assertEquals(hostName, mappedHost.name); + Mapper.Context mappedContext = mappedHost.contextList.contexts[contextPos]; + assertEquals(contextPath, mappedContext.name); + assertEquals(1, mappedContext.versions.length); + assertEquals("0", mappedContext.versions[0].name); + Object oldHost = mappedHost.object; + Object oldContext = mappedContext.versions[0].object; + assertEquals("context2", oldContext.toString()); + + Object oldContext1 = mappedHost.contextList.contexts[contextPos - 1].versions[0].object; + assertEquals("context1", oldContext1.toString()); + + mappingData.recycle(); + mapper.map(hostMB, uriMB, null, mappingData); + assertEquals("blah7", mappingData.host.toString()); + assertEquals("context2", mappingData.context.toString()); + assertEquals("wrapper5", mappingData.wrapper.toString()); + mappingData.recycle(); + mapperForContext2.map(uriMB, mappingData); + assertEquals("wrapper5", mappingData.wrapper.toString()); + + // Mark context as paused + // This is what happens when context reload starts + mapper.pauseContextVersion(oldContext, hostName, contextPath, "0"); + + mappingData.recycle(); + mapper.map(hostMB, uriMB, null, mappingData); + assertEquals("blah7", mappingData.host.toString()); + assertEquals("context2", mappingData.context.toString()); + // Wrapper is not mapped for incoming requests if context is paused + assertNull(mappingData.wrapper); + + // Re-add the same context, but different list of wrappers + // This is what happens when context reload completes + mapper.addContextVersion( + hostName, + oldHost, + contextPath, + "0", + oldContext, + null, + null, + Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo( + "/", "newDefaultWrapper", false, false) })); + + mappedContext = mappedHost.contextList.contexts[contextPos]; + assertEquals(contextPath, mappedContext.name); + assertEquals(1, mappedContext.versions.length); + assertEquals("0", mappedContext.versions[0].name); + + mappingData.recycle(); + mapper.map(hostMB, uriMB, null, mappingData); + assertEquals("blah7", mappingData.host.toString()); + assertEquals("context2", mappingData.context.toString()); + assertEquals("newDefaultWrapper", mappingData.wrapper.toString()); } @Test Modified: tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapperWebapps.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapperWebapps.java?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapperWebapps.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/tomcat/util/http/mapper/TestMapperWebapps.java Tue Aug 26 11:50:42 2014 @@ -85,7 +85,7 @@ public class TestMapperWebapps extends T } @Test - public void testContextReload_Bug56658() throws Exception { + public void testContextReload_Bug56658_Bug56882() throws Exception { Tomcat tomcat = getTomcatInstance(); File appDir = new File(getBuildDirectory(), "webapps/examples"); @@ -113,6 +113,24 @@ public class TestMapperWebapps extends T text = res.toString(); Assert.assertTrue(text, text.contains("<title>Apache Tomcat Examples</title>")); + long timeA = System.currentTimeMillis(); + res = getUrl("http://localhost:" + getPort() + + "/examples/jsp/include/include.jsp"); + String timestamp = findCommonPrefix(timeA, System.currentTimeMillis()); + text = res.toString(); + Assert.assertTrue(text, text.contains( + "In place evaluation of another JSP which gives you the current time: " + timestamp)); + Assert.assertTrue(text, text.contains( + "To get the current time in ms")); + Assert.assertTrue(text, text.contains( + "by including the output of another JSP: " + timestamp)); + Assert.assertTrue(text, text.contains(":-)")); + + res = getUrl("http://localhost:" + getPort() + + "/examples/jsp/forward/forward.jsp"); + text = res.toString(); + Assert.assertTrue(text, text.contains("VM Memory usage")); + ctxt.reload(); res = getUrl("http://localhost:" + getPort() @@ -128,6 +146,24 @@ public class TestMapperWebapps extends T res = getUrl("http://localhost:" + getPort() + "/examples/index.html"); text = res.toString(); Assert.assertTrue(text, text.contains("<title>Apache Tomcat Examples</title>")); + + timeA = System.currentTimeMillis(); + res = getUrl("http://localhost:" + getPort() + + "/examples/jsp/include/include.jsp"); + timestamp = findCommonPrefix(timeA, System.currentTimeMillis()); + text = res.toString(); + Assert.assertTrue(text, text.contains( + "In place evaluation of another JSP which gives you the current time: " + timestamp)); + Assert.assertTrue(text, text.contains( + "To get the current time in ms")); + Assert.assertTrue(text, text.contains( + "by including the output of another JSP: " + timestamp)); + Assert.assertTrue(text, text.contains(":-)")); + + res = getUrl("http://localhost:" + getPort() + + "/examples/jsp/forward/forward.jsp"); + text = res.toString(); + Assert.assertTrue(text, text.contains("VM Memory usage")); } @Test @@ -187,4 +223,17 @@ public class TestMapperWebapps extends T new HashMap<String,List<String>>()); Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc); } + + /** + * Prepare a string to search in messages that contain a timestamp, when it + * is known that the timestamp was printed between {@code timeA} and + * {@code timeB}. + */ + private static String findCommonPrefix(long timeA, long timeB) { + while ((timeA != timeB) && timeA > 0) { + timeA /= 10; + timeB /= 10; + } + return String.valueOf(timeA); + } } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Tue Aug 26 11:50:42 2014 @@ -98,6 +98,10 @@ <bug>56825</bug>: Enable pre-emptive authentication to work with the SSL authenticator. Based on a patch by jlmonteiro. (markt) </fix> + <scode> + <bug>56882</bug>: Add testcase for processing of forwards and includes + when Context have been reloaded. (kkolinko) + </scode> </changelog> </subsection> <subsection name="Coyote"> Modified: tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/one.jsp URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/one.jsp?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/one.jsp (original) +++ tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/one.jsp Tue Aug 26 11:50:42 2014 @@ -19,5 +19,5 @@ <body bgcolor="white"> <font color="red"> -VM Memory usage < 50%. +VM Memory usage < 50%. </html> \ No newline at end of file Modified: tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/two.html URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/two.html?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/two.html (original) +++ tomcat/tc7.0.x/trunk/webapps/examples/jsp/forward/two.html Tue Aug 26 11:50:42 2014 @@ -19,5 +19,5 @@ <body bgcolor="white"> <font color="red"> -VM Memory usage > 50%. +VM Memory usage > 50%. </html> \ No newline at end of file Modified: tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/foo.jsp URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/foo.jsp?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/foo.jsp (original) +++ tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/foo.jsp Tue Aug 26 11:50:42 2014 @@ -13,9 +13,5 @@ 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. ---%> -<body bgcolor="white"> -<font color="red"> - -<%= System.currentTimeMillis() %> +--%><%= System.currentTimeMillis() %> Modified: tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/include.jsp URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/include.jsp?rev=1620577&r1=1620576&r2=1620577&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/include.jsp (original) +++ tomcat/tc7.0.x/trunk/webapps/examples/jsp/include/include.jsp Tue Aug 26 11:50:42 2014 @@ -22,14 +22,9 @@ <%@ page buffer="5kb" autoFlush="false" %> -<p>In place evaluation of another JSP which gives you the current time: - -<%@ include file="foo.jsp" %> - -<p> <jsp:include page="foo.html" flush="true"/> by including the output of another JSP: - -<jsp:include page="foo.jsp" flush="true"/> +<p>In place evaluation of another JSP which gives you the current time: <%@ include file="foo.jsp" %> +<p> <jsp:include page="foo.html" flush="true"/> by including the output of another JSP: <jsp:include page="foo.jsp" flush="true"/> :-) </html> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org