Commits

Allan Crooks committed 8e106b7

Modify test_file_stream so that it tolerates more socket buffering than was previously allowed. Fixes #1199.

  • Participants
  • Parent commits ba63f29

Comments (0)

Files changed (1)

File cherrypy/test/test_static.py

 curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
 has_space_filepath = os.path.join(curdir, 'static', 'has space.html')
 bigfile_filepath = os.path.join(curdir, "static", "bigfile.log")
-BIGFILE_SIZE = 1024 * 1024
+
+# The file size needs to be big enough such that half the size of it
+# won't be socket-buffered (or server-buffered) all in one go. See
+# test_file_stream.
+BIGFILE_SIZE = 1024 * 1024 * 4
 
 import cherrypy
 from cherrypy.lib import static
     def setup_server():
         if not os.path.exists(has_space_filepath):
             open(has_space_filepath, 'wb').write(ntob('Hello, world\r\n'))
-        if not os.path.exists(bigfile_filepath):
+        if not os.path.exists(bigfile_filepath) or \
+            os.path.getsize(bigfile_filepath) != BIGFILE_SIZE:
             open(bigfile_filepath, 'wb').write(ntob("x" * BIGFILE_SIZE))
 
         class Root:
             else:
                 tell_position = int(b)
 
-            expected = len(body)
+            read_so_far = len(body)
+
+            # It is difficult for us to force the server to only read
+            # the bytes that we ask for - there are going to be buffers
+            # inbetween.
+            #
+            # CherryPy will attempt to write as much data as it can to
+            # the socket, and we don't have a way to determine what that
+            # size will be. So we make the following assumption - by
+            # the time we have read in the entire file on the server,
+            # we will have at least received half of it. If this is not
+            # the case, then this is an indicator that either:
+            #   - machines that are running this test are using buffer
+            #     sizes greater than half of BIGFILE_SIZE; or
+            #   - streaming is broken.
+            #
+            # At the time of writing, we seem to have encountered
+            # buffer sizes bigger than 512K, so we've increased
+            # BIGFILE_SIZE to 4MB.
             if tell_position >= BIGFILE_SIZE:
-                # We can't exactly control how much content the server asks
-                # for.
-                # Fudge it by only checking the first half of the reads.
-                if expected < (BIGFILE_SIZE / 2):
+                if read_so_far < (BIGFILE_SIZE / 2):
                     self.fail(
                         "The file should have advanced to position %r, but "
                         "has already advanced to the end of the file. It "
                         "may not be streamed as intended, or at the wrong "
-                        "chunk size (64k)" % expected)
-            elif tell_position < expected:
+                        "chunk size (64k)" % read_so_far)
+            elif tell_position < read_so_far:
                 self.fail(
                     "The file should have advanced to position %r, but has "
                     "only advanced to position %r. It may not be streamed "
-                    "as intended, or at the wrong chunk size (65536)" %
-                    (expected, tell_position))
+                    "as intended, or at the wrong chunk size (64k)" %
+                    (read_so_far, tell_position))
 
         if body != ntob("x" * BIGFILE_SIZE):
             self.fail("Body != 'x' * %d. Got %r instead (%d bytes)." %
         if self.body != ntob("x" * BIGFILE_SIZE):
             self.fail("Body != 'x' * %d. Got %r instead (%d bytes)." %
                       (BIGFILE_SIZE, self.body[:50], len(body)))
-                      
+
     def test_error_page_with_serve_file(self):
         self.getPage("/404test/yunyeen")
         self.assertStatus(404)