Ticket #2839: call-stop-producing.patch

File call-stop-producing.patch, 3.9 KB (added by John Popplewell, 7 years ago)
  • twisted/internet/_pollingfile.py

     
    227227
    228228    def writeConnectionLost(self):
    229229        self.deactivate()
     230        if self.producer:
     231            self.producer.stopProducing()
     232            self.producer = None
    230233        try:
    231234            win32api.CloseHandle(self.writePipe)
    232235        except pywintypes.error:
  • twisted/internet/test/test_pollingfile.py

     
    44"""
    55Tests for L{twisted.internet._pollingfile}.
    66"""
     7import os
    78
    89from twisted.python.runtime import platform
    910from twisted.trial.unittest import TestCase
     11from twisted.protocols import basic
     12from twisted.internet.test.reactormixins import ReactorBuilder
    1013
     14
     15
    1116if platform.isWindows():
     17    import win32pipe
     18    import win32security
     19
    1220    from twisted.internet import _pollingfile
     21
     22    from twisted.internet._pollingfile import _PollingTimer
     23    _skipNotWindows = None
    1324else:
    14     _pollingfile = None
     25    _skipNotWindows = "Test will run only on Windows."
     26    _PollingTimer = object
     27 
    1528
     29 
     30class PipeRunner(_PollingTimer):
     31    """
     32    Builds, initializes and runs a pair of read/write pipes.
     33    """
     34    def __init__(self, pipeSize, doneReadCB, doneWriteCB, receivedCB, reactor):
     35        _PollingTimer.__init__(self, reactor)
     36        sAttrs = win32security.SECURITY_ATTRIBUTES()
     37        sAttrs.bInheritHandle = 1
     38        hRead, hWrite = win32pipe.CreatePipe(sAttrs, pipeSize)
     39        self.reader = _pollingfile._PollableReadPipe(hRead, receivedCB, doneReadCB)
     40        self.writer = _pollingfile._PollableWritePipe(hWrite, doneWriteCB)
     41        self._addPollableResource(self.reader)
     42        self._addPollableResource(self.writer)
    1643
    1744
     45
     46class TestPollablePipes(ReactorBuilder):
     47    """
     48    Tests for L{_pollingfile._PollableWritePipe} and
     49    L{_pollingfile._PollableReadPipe}.
     50    """
     51    def test_callStopProducingWhenDisconnected(self):
     52        """
     53        Test write pipe as a consumer using a push producer when the
     54        connection is forcibly disconnected.
     55       
     56        When a consumer is forcibly disconnected it should call the
     57        stopProducing() method on the producer.
     58
     59        See Ticket #2839: stopProducing() not called.
     60        """
     61        pipeSize = 4096
     62        testMessage = '01234'
     63
     64        class TestProtocol(basic.LineReceiver):
     65            def lineReceived(self, line):
     66                self.testResponse = line
     67                transport.reader.close()
     68
     69        class TestProducer(object):
     70            stopCount = 0
     71            def resumeProducing(self):
     72                transport.writer.write(testMessage+"\r\n")
     73
     74            def pauseProducing(self):
     75                pass
     76
     77            def stopProducing(self):
     78                self.stopCount += 1
     79
     80        reactor = self.buildReactor()
     81        r, w = lambda: None, lambda: reactor.stop()
     82        protocol, producer = TestProtocol(), TestProducer()
     83        transport = PipeRunner(pipeSize, r, w, protocol.dataReceived, reactor)
     84        transport.writer.registerProducer(producer, True)
     85        producer.resumeProducing()
     86        self.runReactor(reactor)
     87        self.assertEqual(testMessage, protocol.testResponse)
     88        self.assertEqual(1, producer.stopCount)
     89
     90
     91globals().update(TestPollablePipes.makeTestCaseClasses())
     92
     93
    1894class TestPollableWritePipe(TestCase):
    1995    """
    2096    Tests for L{_pollingfile._PollableWritePipe}.
     
    41117
    42118
    43119
     120if _skipNotWindows:
     121    TestPollablePipes.skip = skipMessage
     122    TestPollableWritePipeUnicode.skip = skipMessage
    44123
    45 if _pollingfile is None:
    46     TestPollableWritePipe.skip = "Test will run only on Windows."