Commit a3f47e39 authored by Guido van Rossum's avatar Guido van Rossum

"Unbuffered" mode of class _fileobject wasn't actually unbuffered,

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.)
parent a330a5d2
......@@ -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 = [ ]
......
......@@ -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__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment