]> granicus.if.org Git - python/commitdiff
"Unbuffered" mode of class _fileobject wasn't actually unbuffered,
authorGuido van Rossum <guido@python.org>
Wed, 7 Aug 2002 15:46:19 +0000 (15:46 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 7 Aug 2002 15:46:19 +0000 (15:46 +0000)
and this broke a Zope "pipelining" test which read multiple responses
from the same connection (this attaches a new file object to the
socket for each response).  Added a test for this too.

(I want to do some code cleanup too, but I thought I'd first fix
the problem with as little code as possible, and add a unit test
for this case.  So that's what this checkin is about.)

Lib/socket.py
Lib/test/test_socket.py

index 515d47750444d6ff33b708e99ecf190e08cda79a..e59e6d996108ab91e51dbe32aef57d32c26987e4 100644 (file)
@@ -174,11 +174,14 @@ class _socketobject:
 class _fileobject:
     """Implements a file object on top of a regular socket object."""
 
-    def __init__(self, sock, mode='rb', bufsize=8192):
+    def __init__(self, sock, mode='rb', bufsize=-1):
         self._sock = sock
         self._mode = mode
         if bufsize <= 0:
-            bufsize = 512
+           if bufsize == 0:
+               bufsize = 1 # Unbuffered mode
+           else:
+                bufsize = 8192
         self._rbufsize = bufsize
         self._wbufsize = bufsize
         self._rbuf = [ ]
index 737b4310d65ba0605ca11416ab9e7e54eadfe709..ec3ed57dc3723c54e2fbaab07cbe19f0dbd74400 100644 (file)
@@ -502,12 +502,14 @@ class NonBlockingTCPTests(ThreadedTCPSocketTest):
 
 class FileObjectClassTestCase(SocketConnectedTest):
 
+    bufsize = -1 # Use default buffer size
+
     def __init__(self, methodName='runTest'):
         SocketConnectedTest.__init__(self, methodName=methodName)
 
     def setUp(self):
         SocketConnectedTest.setUp(self)
-        self.serv_file = socket._fileobject(self.cli_conn, 'rb', 8192)
+        self.serv_file = self.cli_conn.makefile('rb', self.bufsize)
 
     def tearDown(self):
         self.serv_file.close()
@@ -516,7 +518,7 @@ class FileObjectClassTestCase(SocketConnectedTest):
 
     def clientSetUp(self):
         SocketConnectedTest.clientSetUp(self)
-        self.cli_file = socket._fileobject(self.serv_conn, 'rb', 8192)
+        self.cli_file = self.serv_conn.makefile('wb')
 
     def clientTearDown(self):
         self.cli_file.close()
@@ -557,13 +559,40 @@ class FileObjectClassTestCase(SocketConnectedTest):
         self.cli_file.write(MSG)
         self.cli_file.flush()
 
+class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
+
+    """Repeat the tests from FileObjectClassTestCase with bufsize==0.
+    
+    In this case (and in this case only), it should be possible to
+    create a file object, read a line from it, create another file
+    object, read another line from it, without loss of data in the
+    first file object's buffer.  Note that httplib relies on this
+    when reading multiple requests from the same socket."""
+
+    bufsize = 0 # Use unbuffered mode
+
+    def testUnbufferedReadline(self):
+        """Read a line, create a new file object, read another line with it."""
+        line = self.serv_file.readline() # first line
+       self.assertEqual(line, MSG) # first line
+        self.serv_file = self.cli_conn.makefile('rb', 0)
+        line = self.serv_file.readline() # second line
+       self.assertEqual(line, MSG) # second line
+
+    def _testUnbufferedReadline(self):
+        self.cli_file.write(MSG)
+        self.cli_file.write(MSG)
+        self.cli_file.flush()
+
+
 def test_main():
     suite = unittest.TestSuite()
-    suite.addTest(unittest.makeSuite(GeneralModuleTests))
-    suite.addTest(unittest.makeSuite(BasicTCPTest))
-    suite.addTest(unittest.makeSuite(BasicUDPTest))
-    suite.addTest(unittest.makeSuite(NonBlockingTCPTests))
+    ##suite.addTest(unittest.makeSuite(GeneralModuleTests))
+    ##suite.addTest(unittest.makeSuite(BasicTCPTest))
+    ##suite.addTest(unittest.makeSuite(BasicUDPTest))
+    ##suite.addTest(unittest.makeSuite(NonBlockingTCPTests))
     suite.addTest(unittest.makeSuite(FileObjectClassTestCase))
+    suite.addTest(unittest.makeSuite(UnbufferedFileObjectClassTestCase))
     test_support.run_suite(suite)
 
 if __name__ == "__main__":