[Checkins] SVN: zc.ngi/trunk/ Bug Fixed:
Jim Fulton
jim at zope.com
Tue Jul 27 10:42:39 EDT 2010
Log message for revision 115124:
Bug Fixed:
When using zc.ngi.testing and a server sent input and closed a
connection before set_handler was called on the client, the input
sent by the server was lost.
Changed:
U zc.ngi/trunk/README.txt
U zc.ngi/trunk/src/zc/ngi/testing.py
U zc.ngi/trunk/src/zc/ngi/tests.py
-=-
Modified: zc.ngi/trunk/README.txt
===================================================================
--- zc.ngi/trunk/README.txt 2010-07-27 14:33:09 UTC (rev 115123)
+++ zc.ngi/trunk/README.txt 2010-07-27 14:42:39 UTC (rev 115124)
@@ -20,6 +20,16 @@
*******
====================
+2.0.0a4 (2010-07-27)
+====================
+
+Bugs Fixed:
+
+- When using zc.ngi.testing and a server sent input and closed a
+ connection before set_handler was called on the client, the input
+ sent by the server was lost.
+
+====================
2.0.0a3 (2010-07-22)
====================
Modified: zc.ngi/trunk/src/zc/ngi/testing.py
===================================================================
--- zc.ngi/trunk/src/zc/ngi/testing.py 2010-07-27 14:33:09 UTC (rev 115123)
+++ zc.ngi/trunk/src/zc/ngi/testing.py 2010-07-27 14:42:39 UTC (rev 115124)
@@ -50,10 +50,9 @@
def __init__(self, peer=None, handler=PrintingHandler):
self.handler = None
- self.closed = False
- self.input = ''
- self.exception = None
+ self.handler_queue = []
self.control = None
+ self.closed = None
if peer is None:
peer = Connection(self)
handler(peer)
@@ -63,12 +62,26 @@
return not self.closed
queue = None
- def _callHandler(self, method, *args):
+ def _callHandler(self, method, arg):
+ if self.handler is None:
+ queue = self.handler_queue
+ if (method == 'handle_input' and queue and queue[-1][0] == method):
+ # combine inputs
+ queue[-1] = method, queue[-1][1]+arg
+ else:
+ queue.append((method, arg))
+ return
+
if self.queue is None:
- self.queue = [(method, args)]
- while self.queue:
- method, args = self.queue.pop(0)
- if self.closed and method != 'handle_close':
+ self.queue = queue = [(method, arg)]
+ while queue:
+ method, arg = queue.pop(0)
+
+ if method == 'handle_close':
+ if self.control is not None:
+ self.control.closed(self)
+ self.closed = arg
+ elif self.closed:
break
try:
@@ -84,11 +97,11 @@
None)
if handler is None:
return
- args = self, 'unhandled exception'
+ arg = 'unhandled exception'
else:
raise
- handler(self, *args)
+ handler(self, arg)
except:
print "Error test connection calling connection handler:"
traceback.print_exc(file=sys.stdout)
@@ -98,7 +111,7 @@
self.queue = None
else:
- self.queue.append((method, args))
+ self.queue.append((method, arg))
def close(self):
self.peer.test_close('closed')
@@ -111,37 +124,23 @@
def set_handler(self, handler):
self.handler = handler
- if self.exception:
- exception = self.exception
- self.exception = None
- self._callHandler('handle_exception', exception)
- if self.input:
- self._callHandler('handle_input', self.input)
- self.input = ''
+ while self.handler_queue:
+ self._callHandler(*self.handler_queue.pop(0))
- # Note is self.closed is True, we self closed and we
- # don't want to call handle_close.
- if self.closed and isinstance(self.closed, str):
- self._callHandler('handle_close', self.closed)
-
def setHandler(self, handler):
warnings.warn("setHandler is deprecated. Use set_handler,",
DeprecationWarning, stacklevel=2)
self.set_handler(handler)
def test_input(self, data):
- if self.handler is not None:
- self._callHandler('handle_input', data)
- else:
- self.input += data
+ self._callHandler('handle_input', data)
def test_close(self, reason):
- if self.control is not None:
- self.control.closed(self)
- self.closed = reason
- if self.handler is not None:
- self._callHandler('handle_close', reason)
+ self._callHandler('handle_close', reason)
+ def _exception(self, exception):
+ self._callHandler('handle_exception', exception)
+
def write(self, data):
if data is zc.ngi.END_OF_DATA:
return self.close()
@@ -162,12 +161,6 @@
except Exception, v:
self._exception(v)
- def _exception(self, exception):
- if self.handler is None:
- self.exception = exception
- else:
- self._callHandler('handle_exception', exception)
-
class _ServerConnection(Connection):
zc.ngi.interfaces.implements(zc.ngi.interfaces.IServerConnection)
Modified: zc.ngi/trunk/src/zc/ngi/tests.py
===================================================================
--- zc.ngi/trunk/src/zc/ngi/tests.py 2010-07-27 14:33:09 UTC (rev 115123)
+++ zc.ngi/trunk/src/zc/ngi/tests.py 2010-07-27 14:42:39 UTC (rev 115124)
@@ -23,6 +23,7 @@
import time
import unittest
import warnings
+import zc.ngi.adapters
import zc.ngi.async
import zc.ngi.generator
import zc.ngi.testing
@@ -577,7 +578,29 @@
>>> listener.close()
"""
+def testing_connection_processes_close_and_input_before_set_handler_in_order():
+ r"""
+If we are using test connections and the server sends input and closes
+the connection before the client handler is set, the client must see the input:
+ >>> @zc.ngi.adapters.Lines.handler
+ ... def server(c):
+ ... c.write((yield).upper()+'\n')
+
+ >>> listener = zc.ngi.testing.listener('x', server)
+
+ >>> @zc.ngi.adapters.Lines.handler
+ ... def client(c):
+ ... c.write('test\n')
+ ... print (yield)
+
+ >>> zc.ngi.testing.connect('x', client)
+ TEST
+
+ >>> listener.close()
+"""
+
+
if sys.version_info < (2, 6):
del setHandler_compatibility
More information about the checkins
mailing list