def test_sackNumberTooHigh(self): q = Queue() q.extend(['zero', 'one', 'two', 'three']) badSACK = q.handleSACK(SACK(0, (2, 5))) self.assertEqual(True, badSACK) # Items were still removed, despite it being a bad SACK self.assertEqual([(1, 'one'), (3, 'three')], list(q.iterItems()))
def test_ackNumberTooHigh1(self): q = Queue() q.append('zero') badSACK = q.handleSACK(SACK(1, ())) self.assertEqual(True, badSACK) # Items were still removed, despite it being a bad SACK self.assertEqual([], list(q.iterItems()))
def test_handleSACKToHigherNum(self): q = Queue() q.extend(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']) self.assertEqual(False, q.handleSACK(SACK(1, ()))) self.assertEqual(False, q.handleSACK(SACK(3, ()))) # There should be 5 items left in the queue self.assertEqual([(4,'4'), (5,'5'), (6,'6'), (7,'7'), (8,'8'), (9,'9'), (10,'10')], list(q.iterItems(start=4)))
def test_handleSACKBothAckAndSackNumRemoveItems(self): """ Another handleSACK test. This covers a wrong-variable-in-loop bug we had. """ q = Queue() q.extend(['zero', 'one', 'two', 'three', 'four']) self.assertEqual(False, q.handleSACK(SACK(0, (1, 3)))) self.assertEqual([(2, 'two'), (4, 'four')], list(q.iterItems()))
def test_iterItemsNoStartNumber(self): """ A L{start} for iterItems is not required. """ q = Queue() q.append('zero') q.extend(['one', 'two']) self.assertEqual([(0, 'zero'), (1, 'one'), (2, 'two')], list(q.iterItems())) self.assertEqual(False, q.handleSACK(SACK(-1, ()))) self.assertEqual([(0, 'zero'), (1, 'one'), (2, 'two')], list(q.iterItems())) self.assertEqual(False, q.handleSACK(SACK(0, ()))) self.assertEqual([(1, 'one'), (2, 'two')], list(q.iterItems()))
def test_repr(self): q = Queue() self.assertEqual('<Queue at 0x%x with 0 item(s), counter=#-1, ' 'size=0>' % (id(q),), repr(q)) q.extend(['a', 'b']) self.assertEqual('<Queue at 0x%x with 2 item(s), counter=#1, ' 'size=%d>' % (id(q), totalSizeOf('a') * 2), repr(q)) q.handleSACK(SACK(0, ())) self.assertEqual('<Queue at 0x%x with 1 item(s), counter=#1, ' 'size=%d>' % (id(q), totalSizeOf('a')), repr(q))
def test_handleSACKOnlyAckNumber(self): q = Queue() q.append('zero') q.extend(['one', 'two']) self.assertEqual(False, q.handleSACK(SACK(0, ()))) self.assertEqual([(1, 'one'), (2, 'two')], list(q.iterItems(start=1))) # Removing again is idempotent self.assertEqual(False, q.handleSACK(SACK(0, ()))) self.assertEqual([(1, 'one'), (2, 'two')], list(q.iterItems(start=1)))
def test_appendExtendQueueStart3(self): q = Queue() q.append('zero') q.extend(['one', 'two']) self.assertEqual([], list(q.iterItems(start=3))) # iterItems is idempotent self.assertEqual([], list(q.iterItems(start=3)))
def test_appendExtendQueue(self): q = Queue() q.append('zero') q.extend(['one', 'two']) self.assertEqual([(0, 'zero'), (1, 'one'), (2, 'two')], list(q.iterItems(start=0))) # iterItems is idempotent self.assertEqual([(0, 'zero'), (1, 'one'), (2, 'two')], list(q.iterItems(start=0)))
def __init__(self, clock=None, streamId=None, streamProtocolFactory=None): ## if streamId is None: # make a random one? self._notifications = [] self.streamId = streamId self.streamProtocolFactory = streamProtocolFactory self.log = ListLog() self._incoming = Incoming() self.queue = Queue() self._transports = set() self.allSeenTransports = [] self.lastSackSeenByServer = SACK(-1, ())
class MockServerStream(object): streamId = "a stream id of unusual length" def __init__(self, clock=None, streamId=None, streamProtocolFactory=None): ## if streamId is None: # make a random one? self._notifications = [] self.streamId = streamId self.streamProtocolFactory = streamProtocolFactory self.log = ListLog() self._incoming = Incoming() self.queue = Queue() self._transports = set() self.allSeenTransports = [] self.lastSackSeenByServer = SACK(-1, ()) def getNew(self): return self.log.getNew() def sendString(self, string): self.log.append(['sendString', string]) def reset(self, reasonString): self.log.append(['reset', reasonString]) def resetFromPeer(self, reasonString, applicationLevel): self.log.append(['resetFromPeer', reasonString, applicationLevel]) for t in self._transports.copy(): t.closeGently() def stringsReceived(self, transport, strings): self.log.append(['stringsReceived', transport, strings]) self._incoming.give(strings) def sackReceived(self, sack): """ Returns C{True} if SACK was bad, C{False} otherwise. """ self.log.append(['sackReceived', sack]) self.lastSackSeenByServer = sack return self.queue.handleSACK(sack) def transportOnline(self, transport, wantsStrings, succeedsTransport): self.allSeenTransports.append(transport) self.log.append(['transportOnline', transport, wantsStrings, succeedsTransport]) assert transport not in self._transports self._transports.add(transport) def transportOffline(self, transport): self.log.append(['transportOffline', transport]) self._transports.remove(transport) def serverShuttingDown(self, transport): self.log.append(['serverShuttingDown', transport]) def pauseProducing(self): self.log.append(['pauseProducing']) def resumeProducing(self): self.log.append(['resumeProducing']) def stopProducing(self): self.log.append(['stopProducing']) def getSACK(self): self.log.append(['getSACK']) return self._incoming.getSACK() def notifyFinish(self): """ Notify when finishing the request @return: A deferred. The deferred will be triggered when the stream is finished -- always with a C{None} value. """ self.log.append(['notifyFinish']) self._notifications.append(defer.Deferred()) return self._notifications[-1] def _pretendFinish(self): for d in self._notifications: d.callback(None) self._notifications = None
def test_ackNumberTooHigh0(self): q = Queue() badSACK = q.handleSACK(SACK(0, ())) self.assertEqual(True, badSACK)
def test_iterEmptyQueue(self): q = Queue() self.assertEqual([], list(q.iterItems(start=0)))
def test_getMaxConsumption(self): """ The size of the Queue increases when we extend it or append to it, and decreases when we give it an ackNumber or sackNum that causes it to remove items. """ q = Queue() self.assertEqual(0, q.getMaxConsumption()) q.extend(['a', 'b']) self.assertEqual(totalSizeOf('a') * 2, q.getMaxConsumption()) q.handleSACK(SACK(0, ())) self.assertEqual(totalSizeOf('a'), q.getMaxConsumption()) # strange-looking SACK, but it does exercise the code we want to exercise q.handleSACK(SACK(0, (1,))) self.assertEqual(0, q.getMaxConsumption()) q.handleSACK(SACK(1, ())) self.assertEqual(0, q.getMaxConsumption()) q.append('cc') self.assertEqual(totalSizeOf('cc'), q.getMaxConsumption())
def test_handleSACK(self): """ handleSACK actually removes the selectively-acknowledged items from the queue """ q = Queue() q.append('zero') q.extend(['one', 'two', 'three']) self.assertEqual([(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three')], list(q.iterItems())) self.assertEqual(False, q.handleSACK(SACK(-1, (1,)))) self.assertEqual([(0, 'zero'), (2, 'two'), (3, 'three')], list(q.iterItems())) self.assertEqual(False, q.handleSACK(SACK(0, (3,)))) self.assertEqual([(2, 'two')], list(q.iterItems())) q.append('four') self.assertEqual([(2, 'two'), (4, 'four')], list(q.iterItems())) # although this is a very strange SACK because it should have # been (4, ()), it is still legal self.assertEqual(False, q.handleSACK(SACK(0, (2, 4)))) self.assertEqual([], list(q.iterItems())) q.append('five') self.assertEqual([(5, 'five')], list(q.iterItems()))