From 37059788f3b700ec3498964a49509a5143156eaa Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 5 Aug 2009 23:56:31 +0000 Subject: [PATCH] Fixing test failures in RFC2616 section 9.4 * A timing issue was discovered in the test case (not a bug in jetty), added some code to filter out the "Date: " header as there can be a difference in that header between the GET and HEAD calls. git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@645 7e9141cc-0065-0410-87d8-b60c137991c4 --- .../org/eclipse/jetty/test/StringAssert.java | 26 ++++++++- .../jetty/test/rfcs/RFC2616BaseTest.java | 51 ++++++++++------- .../jetty/test/support/StringUtil.java | 55 +++++++++++++++++-- 3 files changed, 106 insertions(+), 26 deletions(-) diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/StringAssert.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/StringAssert.java index a5eabe08af2..d69ecc664f4 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/StringAssert.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/StringAssert.java @@ -5,17 +5,19 @@ // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.apache.org/licenses/LICENSE-2.0.txt // -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.test; +import java.util.List; + import junit.framework.Assert; import junit.framework.AssertionFailedError; @@ -165,4 +167,24 @@ public class StringAssert throw new AssertionFailedError(buf.toString()); } } + + /** + * Asserts that the list of String lines contains the same lines (without a regard for the order of those lines) + * + * @param msg + * the assertion message + * @param linesExpected + * the list of expected lines + * @param linesActual + * the list of actual lines + */ + public static void assertContainsSame(String msg, List linesExpected, List linesActual) + { + Assert.assertEquals(msg + " line count",linesExpected.size(),linesActual.size()); + + for (String expected : linesExpected) + { + Assert.assertTrue(msg + ": expecting to see line <" + expected + ">",linesActual.contains(expected)); + } + } } diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java index 5d65fe87cce..f0b1bb12001 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/rfcs/RFC2616BaseTest.java @@ -5,13 +5,13 @@ // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.apache.org/licenses/LICENSE-2.0.txt // -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.test.rfcs; @@ -89,9 +89,9 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase { testWorkDir.mkdirs(); } - + System.setProperty("java.io.tmpdir",testWorkDir.getAbsolutePath()); - + server = getJettyServer(); server.load(); server.start(); @@ -805,7 +805,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase assertEquals("Response Count",2,responses.size()); // Should have 2 responses - response = responses.get(0); // Only interested in first response + response = responses.get(0); // Only interested in first response response.assertHeaderExists("9.2 OPTIONS","Allow"); // Header expected ... // Allow: GET, HEAD, POST, TRACE, OPTIONS @@ -862,7 +862,20 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase int headResponseLength = rawHeadResponse.length(); // Only interested in the response header from the GET request above. String rawGetResponse = response.getRawResponse().toString().substring(0,headResponseLength); - assertEquals("9.4 HEAD equals GET",rawHeadResponse,rawGetResponse); + + // As there is a possibility that the time between GET and HEAD requests + // can cross the second mark. (eg: GET at 11:00:00.999 and HEAD at 11:00:01.001) + // So with that knowledge, we will remove the 'Date:' header from both sides before comparing. + List linesGet = StringUtil.asLines(rawGetResponse); + List linesHead = StringUtil.asLines(rawHeadResponse); + + StringUtil.removeStartsWith("Date: ",linesGet); + StringUtil.removeStartsWith("Date: ",linesHead); + + // Compare the 2 lists of lines to make sure they contain the same information + // Do not worry about order of the headers, as that's not important to test, + // just the existence of the same headers + StringAssert.assertContainsSame("9.4 HEAD equals GET",linesGet,linesHead); } finally { @@ -932,8 +945,8 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase response.assertStatus("10.2.7 Partial Content",HttpStatus.PARTIAL_CONTENT_206); - // (point 1) A 206 response MUST contain either a Content-Range header - // field (section 14.16) indicating the range included with this + // (point 1) A 206 response MUST contain either a Content-Range header + // field (section 14.16) indicating the range included with this // response, or a multipart/byteranges Content-Type including Content-Range // fields for each part. If a Content-Length header field is present // in the response, its value MUST match the actual number of OCTETs @@ -952,7 +965,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase // (point 2) A 206 response MUST contain a Date header response.assertHeaderExists("10.2.7 Partial Content / Response / Date","Date"); - // (point 3) A 206 response MUST contain ETag and/or Content-Location, + // (point 3) A 206 response MUST contain ETag and/or Content-Location, // if the header would have been sent in a 200 response to the same request if (noRangeHasContentLocation) { @@ -963,8 +976,8 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase response.assertHeaderExists("10.2.7 Partial Content / Content-Location","ETag"); } - // (point 4) A 206 response MUST contain Expires, Cache-Control, and/or Vary, - // if the field-value might differ from that sent in any previous response + // (point 4) A 206 response MUST contain Expires, Cache-Control, and/or Vary, + // if the field-value might differ from that sent in any previous response // for the same variant // TODO: Not sure how to test this condition. @@ -1122,7 +1135,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase @Test public void test14_16_NoRange() throws Exception { - // + // // calibrate with normal request (no ranges); if this doesnt // work, dont expect ranges to work either // @@ -1141,10 +1154,10 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase private void assertBadContentRange(String rangedef) throws IOException { - // + // // server should ignore all range headers which include // at least one syntactically invalid range - // + // StringBuffer req1 = new StringBuffer(); req1.append("GET /rfc2616-webapp/alpha.txt HTTP/1.1\n"); @@ -1280,7 +1293,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase // should test for combinations of good and syntactically // invalid ranges here, but I am not certain what the right // behavior is anymore - // + // // return data for valid ranges while ignoring unsatisfiable // ranges @@ -1322,7 +1335,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase // should test for combinations of good and syntactically // invalid ranges here, but I am not certain what the right // behavior is anymore - // + // // return data for valid ranges while ignoring unsatisfiable // ranges @@ -1361,7 +1374,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase // should test for combinations of good and syntactically // invalid ranges here, but I am not certain what the right // behavior is anymore - // + // // return data for valid ranges while ignoring unsatisfiable // ranges @@ -1502,7 +1515,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase @Test public void test14_35_Range() throws Exception { - // + // // test various valid range specs that have not been // tested yet // @@ -1657,7 +1670,7 @@ public abstract class RFC2616BaseTest extends AbstractJettyTestCase @Test public void test14_35_PartialRange() throws Exception { - // + // // test various valid range specs that have not been // tested yet // diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java index 6c34557e086..bc520d15d7a 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/support/StringUtil.java @@ -5,21 +5,30 @@ // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // -// The Eclipse Public License is available at +// The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.apache.org/licenses/LICENSE-2.0.txt // -// You may elect to redistribute this code under either of these licenses. +// You may elect to redistribute this code under either of these licenses. // ======================================================================== package org.eclipse.jetty.test.support; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +import org.eclipse.jetty.util.IO; + public class StringUtil { public static final String LN = System.getProperty("line.separator"); - + public static boolean isBlank(String str) { if (str == null) @@ -103,7 +112,7 @@ public class StringUtil return ret; } - + /** * Utility method to convert "\n" found to "\r\n" if running on windows. * @@ -131,10 +140,46 @@ public class StringUtil ret.append(LN); linesep = false; } - ret.append(c); + ret.append(c); } } return ret.toString(); } + + public static List asLines(String raw) throws IOException + { + List lines = new ArrayList(); + StringReader sreader = null; + BufferedReader buf = null; + try + { + sreader = new StringReader(raw); + buf = new BufferedReader(sreader); + String line; + while ((line = buf.readLine()) != null) + { + lines.add(line); + } + } + finally + { + IO.close(buf); + IO.close(sreader); + } + return lines; + } + + public static void removeStartsWith(String prefix, List lines) + { + ListIterator it = lines.listIterator(); + while (it.hasNext()) + { + String line = it.next(); + if (line.startsWith(prefix)) + { + it.remove(); + } + } + } }