def test_simple(self): i = Incoming() _ = i.give([[1, 'string1'], [2, 'string2'], [3, 'string3']]) self.assertEqual(totalSizeOf('string1') * 3, i.getMaxConsumption()) _ = i.give([[4, 'string4'], [5, 'string5'], [6, 'string6']]) self.assertEqual(totalSizeOf('string1') * 6, i.getMaxConsumption())
def test_twoRangesMissingThenFill(self): i = Incoming() self.assertEqual( (['string0', 'string1'], False), i.give([[0, 'string0'], [1, 'string1'], [4, 'string4'], [6, 'string6']])) self.assertEqual(SACK(1, (4, 6)), i.getSACK()) self.assertEqual( (['string2', 'string3', 'string4', 'string5', 'string6'], False), i.give([[2, 'string2'], [3, 'string3'], [5, 'string5']])) self.assertEqual(SACK(6, ()), i.getSACK())
def test_StringFragmentConvertToStr(self): """ L{StringFragment}s are converted to C{window._wasSF}s if they are undeliverable inside L{Incoming}. """ i = Incoming() s = _wasSF("helloworld" * 100) sf = StringFragment(s, 0, len(s)) i.give([[1, sf]]) self.assertEqual(totalSizeOf(s), i.getMaxConsumption())
def test_strConvertedBackToStringFragment(self): """ L{window._wasSF}s are converted back to C{StringFragment}s before being delivered. """ i = Incoming() s = _wasSF("helloworld" * 100) sf = StringFragment(s, 0, len(s)) i.give([[1, sf]]) self.assertEqual(([sf, sf], False), i.give([[0, sf]]))
def test_twoRangesMissingAbove9(self): """ Test that the sackList is sorted by the numeric value of the numbers. This test was ported from Javascript and is not really necessary in Python. """ i = Incoming() self.assertEqual( (['string0', 'string1'], False), i.give([[0, 'string0'], [1, 'string1'], [4, 'string4'], [10, 'string6']])) self.assertEqual(SACK(1, (4, 10)), i.getSACK())
def test_outOfOrderJustOneCall(self): """ L{Incoming} handles all the strings even when they're given out-of-order in one L{Incoming.give} call. You should *not* pass .give unsorted sequences in production code, because you may hit the item/size limit. It will also be slower because it must modify a dictionary more frequently. """ i = Incoming() self.assertEqual((['string0', 'string1'], False), i.give([[1, 'string1'], [0, 'string0']])) self.assertEqual(SACK(1, ()), i.getSACK())
def test_itemSizeChangedWhileInIncoming(self): """ If the size of an item changed while it was in Incoming, Incoming does *not* go into an inconsistent state (for example, thinking that _size is < 0) """ class LengthChangingString(str): def __len__(self2): return self2.sayLength i = Incoming() mutable = LengthChangingString("hi") mutable.sayLength = 2 assert len(mutable) == 2, len(mutable) i.give([[1, mutable]]) sizeBefore = i.getMaxConsumption() self.assertTrue(sizeBefore > 0, sizeBefore) mutable.sayLength = 3 assert len(mutable) == 3, len(mutable) i.give([[0, "0"]]) sizeAfter = i.getMaxConsumption() self.assertEqual(0, sizeAfter)
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 test_outOfOrder(self): i = Incoming() # string0 missing self.assertEqual(([], False), i.give([[1, 'string1'], [2, 'string2']])) self.assertEqual(SACK(-1, (1, 2)), i.getSACK()) # finally deliver it self.assertEqual((['string0', 'string1', 'string2'], False), i.give([[0, 'string0']])) # make sure it still works self.assertEqual((['string3'], False), i.give([[3, 'string3']])) self.assertEqual(SACK(3, ()), i.getSACK())
def test_itemLimit(self): i = Incoming() self.assertEqual(([], False), i.give([[1, 'string1']], itemLimit=3)) self.assertEqual(([], False), i.give([[2, 'string2']], itemLimit=3)) self.assertEqual(([], False), i.give([[3, 'string3']], itemLimit=3)) self.assertEqual(([], True), i.give([[4, 'string4']], itemLimit=3)) self.assertEqual(([], True), i.give([[5, 'string5']], itemLimit=3)) # The items we kept giving it past the limit are dropped to the floor deliverable, hitLimit = i.give([[0, 'string0']], itemLimit=3) self.assertEqual(False, hitLimit) self.assertEqual(['string0', 'string1', 'string2', 'string3'], deliverable) self.assertEqual(0, i.getUndeliverableCount()) self.assertEqual(0, i.getMaxConsumption())
def test_negativeSequenceNum(self): i = Incoming() self.assertRaises(ValueError, lambda: i.give([[-1, 'string']])) self.assertRaises(ValueError, lambda: i.give([[-2, 'string']]))
def test_itemMissing(self): i = Incoming() self.assertEqual( (['string0', 'string1'], False), i.give([[0, 'string0'], [1, 'string1'], [3, 'string3']])) self.assertEqual(SACK(1, (3,)), i.getSACK())
def test_twoRangesMissing(self): i = Incoming() self.assertEqual( (['string0', 'string1'], False), i.give([[0, 'string0'], [1, 'string1'], [4, 'string4'], [6, 'string6']])) self.assertEqual(SACK(1, (4, 6)), i.getSACK())
def test_noStringsEverGiven(self): i = Incoming() self.assertEqual(0, i.getMaxConsumption())
def test_itemsGivenTwice(self): """ If an already-delivered item is given again, it is completely ignored and does not occupy space in the internal cache. """ i = Incoming() i.give([[0, 'string0'], [1, 'string1']]) self.assertEqual(0, i.getUndeliverableCount()) i.give([[0, 'string0']]) self.assertEqual(0, i.getUndeliverableCount()) i.give([[1, 'string1']]) self.assertEqual(0, i.getUndeliverableCount()) i.give([[0, 'string0'], [1, 'string1']]) self.assertEqual(0, i.getUndeliverableCount()) i.give([[0, 'string0'], [1, 'string1'], [2, 'string2']]) self.assertEqual(0, i.getUndeliverableCount())
def test_threeItems(self): i = Incoming() self.assertEqual( (['string0', 'string1', 'string2'], False), i.give([[0, 'string0'], [1, 'string1'], [2, 'string2']])) self.assertEqual(SACK(2, ()), i.getSACK())
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_getUndeliverableCount(self): i = Incoming() self.assertEqual(0, i.getUndeliverableCount()) i.give([[1, 'string1']]) self.assertEqual(1, i.getUndeliverableCount()) i.give([[2, 'string2']]) self.assertEqual(2, i.getUndeliverableCount()) i.give([[0, 'string0']]) self.assertEqual(0, i.getUndeliverableCount())
def test_SACKNoItems(self): i = Incoming() self.assertEqual(SACK(-1, ()), i.getSACK())