def test_packetiseDoc(self, data): doc, encoding, bom, time, marker = data thisTransmitter = TTMLTransmitter("", 0, encoding=encoding, bom=bom) expectedSeqNum = thisTransmitter._nextSeqNum packets = thisTransmitter._packetiseDoc(doc, time) for x in range(len(packets)): payload = RTPPayload_TTML( encoding=encoding, bom=bom).fromBytearray(packets[x].payload) self.assertEqual(packets[x].timestamp, thisTransmitter._datetimeToRTPTs(time)) self.assertEqual(packets[x].sequenceNumber, expectedSeqNum + x) self.assertIn(payload.userDataWords, doc) self.assertLess(len(utfEncode(payload.userDataWords)), 2**16) thisBom = BOMS[encoding] if bom and (x == 0): self.assertTrue(payload._userDataWords.startswith(thisBom)) else: self.assertFalse(payload._userDataWords.startswith(thisBom)) if x == (len(packets) - 1): self.assertTrue(packets[x].marker) else: self.assertFalse(packets[x].marker) self.assertEqual(thisTransmitter.nextSeqNum, expectedSeqNum + len(packets))
def test_userDataWords_encodings(self, data): doc, encoding, bom = data payload = RTPPayload_TTML(userDataWords=doc, encoding=encoding, bom=bom) self.assertEqual(payload.userDataWords, doc) self.assertEqual(payload._userDataWords, utfEncode(doc, encoding, bom))
def test_decode_utf16(self, doc): # UTF-16 can decode both little and big endian for enc in ["UTF-16LE", "UTF-16BE"]: encoded = utfEncode(doc, enc, True) decoded = utfDecode(encoded, "UTF-16") self.assertEqual(doc, decoded)
def test_decode_wrongBom(self, doc): for enc, dec in [("UTF-16LE", "UTF-16BE"), ("UTF-16LE", "UTF-8"), ("UTF-16BE", "UTF-16LE"), ("UTF-16BE", "UTF-8"), ("UTF-8", "UTF-16BE"), ("UTF-8", "UTF-16LE")]: encoded = utfEncode(doc, enc, True) with self.assertRaises(ValueError): utfDecode(encoded, dec)
def test_encode_encodings(self, doc, encoding, bom): ret = utfEncode(doc, encoding, bom) if bom: self.assertTrue(ret.startswith(BOMS[encoding])) ret = ret[len(BOMS[encoding]):] self.assertEqual(doc, ret.decode(ENCODING_ALIASES[encoding]))
def test_fragmentDoc(self, doc, maxLen): fragments = self.transmitter._fragmentDoc(doc, maxLen) reconstructedDoc = "" for fragment in fragments: self.assertLessEqual(len(utfEncode(fragment)), maxLen) reconstructedDoc += fragment self.assertEqual(doc, reconstructedDoc)
def test_toBytearray(self, doc): self.thisP.userDataWords = doc bDoc = utfEncode(doc) expected = bytearray(2) expected += int(len(bDoc)).to_bytes(2, byteorder='big') expected += bDoc self.assertEqual(expected, self.thisP.toBytearray())
def test_fromBytearray(self, doc): expected = RTPPayload_TTML(userDataWords=doc) bDoc = utfEncode(doc) bArray = bytearray(2) bArray += int(len(bDoc)).to_bytes(2, byteorder='big') bArray += bDoc self.thisP.fromBytearray(bArray) self.assertEqual(expected, self.thisP)
def _fragmentDoc(self, doc: str, maxLen: int) -> List[str]: fragments = [] thisStart = 0 if doc == "": return [] while True: thisEnd = thisStart + maxLen while len( utfEncode(doc[thisStart:thisEnd], self._encoding, self._bom)) > maxLen: thisEnd -= 1 fragments.append(doc[thisStart:thisEnd]) if thisEnd >= len(doc): break thisStart = thisEnd return fragments
class TestTTMLReceiver(TestCase): def callback(self, doc, timestamp): self.callbackCallCount += 1 self.callbackValues.append((doc, timestamp)) @mock.patch("socket.socket") def setUp(self, mockSocket): self.callbackCallCount = 0 self.callbackValues = [] self.receiver = TTMLReceiver(0, self.callback) def setup_example(self): self.setUp() def test_unloop(self): msnPlus1 = MAX_SEQ_NUM + 1 # [[prevNum, thisNum, expectedReturnVal]] tests = [[MAX_SEQ_NUM - 1, MAX_SEQ_NUM, MAX_SEQ_NUM], [MAX_SEQ_NUM - 1, 0, MAX_SEQ_NUM + 1], [MAX_SEQ_NUM, 0, MAX_SEQ_NUM + 1], [MAX_SEQ_NUM, 1, MAX_SEQ_NUM + 2], [0, 1, 1], [0, 2, 2], [ msnPlus1 + MAX_SEQ_NUM - 1, MAX_SEQ_NUM, msnPlus1 + MAX_SEQ_NUM ], [msnPlus1 + MAX_SEQ_NUM - 1, 0, msnPlus1 + MAX_SEQ_NUM + 1], [msnPlus1 + MAX_SEQ_NUM, 0, msnPlus1 + MAX_SEQ_NUM + 1], [msnPlus1 + MAX_SEQ_NUM, 1, msnPlus1 + MAX_SEQ_NUM + 2], [msnPlus1, 1, msnPlus1 + 1], [msnPlus1, 2, msnPlus1 + 2]] for test in tests: ret = self.receiver._unloopSeqNum(test[0], test[1]) self.assertEqual(ret, test[2], msg="Failing test: {}".format(test)) @given(st.integers(min_value=0, max_value=MAX_SEQ_NUM), st.lists(st.booleans(), min_size=10, max_size=10)) def test_keysComplete(self, startKey, keepList): assume(keepList[0] is True) for keyOffset in range(10): if keepList[keyOffset]: self.receiver._fragments[startKey + keyOffset] = None complete = True seenFalse = False for keepItem in keepList[1:]: if keepItem is False: seenFalse = True else: if seenFalse: complete = False self.assertEqual(complete, self.receiver._keysComplete()) def test_keysCompleteEmpty(self): self.assertFalse(self.receiver._keysComplete()) @given(st.integers(min_value=0, max_value=MAX_SEQ_NUM), st.lists(st.text(min_size=1), min_size=1)) def test_processFragments(self, startKey, docFragments): expectedDoc = "" for x in range(len(docFragments)): expectedDoc += docFragments[x] self.receiver._fragments[startKey + x] = docFragments[x] self.receiver._processFragments() self.assertEqual(0, len(self.receiver._fragments)) self.assertEqual(1, self.callbackCallCount) self.assertEqual(expectedDoc, self.callbackValues[0][0]) def test_processFragmentsEmpty(self): self.receiver._processFragments() self.assertEqual(0, self.callbackCallCount) @given( st.tuples(st.text(min_size=1), st.sampled_from(SUPPORTED_ENCODINGS), st.booleans()).filter( lambda x: len(utfEncode(x[0], x[1], x[2])) < 2**16)) def test_processPacket(self, data): doc, encoding, bom = data payload = RTPPayload_TTML(userDataWords=doc, encoding=encoding, bom=bom).toBytearray() packet = RTP(payload=payload, marker=True) with mock.patch("rtpTTML.ttmlReceiver.RTPPayload_TTML") as mockTTML: thisReceiver = TTMLReceiver(0, self.callback, encoding=encoding, bom=bom) thisReceiver._processPacket(packet) mockTTML.assert_called_once_with(encoding=encoding, bom=bom) @given( st.tuples(st.text(min_size=1), st.sampled_from(SUPPORTED_ENCODINGS), st.booleans()).filter( lambda x: len(utfEncode(x[0], x[1], x[2])) < 2**16)) def test_processData(self, data): doc, encoding, bom = data payload = RTPPayload_TTML(userDataWords=doc, encoding=encoding, bom=bom).toBytearray() packet = RTP(payload=payload, marker=True) packetBytes = packet.toBytes() with mock.patch("rtpTTML.ttmlReceiver.RTPPayload_TTML") as mockTTML: thisReceiver = TTMLReceiver(0, self.callback, encoding=encoding, bom=bom) thisReceiver._processData(packetBytes) mockTTML.assert_called_once_with(encoding=encoding, bom=bom)
class TestTTMLTransmitter(TestCase): def setUp(self): self.transmitter = TTMLTransmitter("", 0) def setup_example(self): self.setUp() @given(st.text(min_size=1), st.integers(min_value=4)) def test_fragmentDoc(self, doc, maxLen): fragments = self.transmitter._fragmentDoc(doc, maxLen) reconstructedDoc = "" for fragment in fragments: self.assertLessEqual(len(utfEncode(fragment)), maxLen) reconstructedDoc += fragment self.assertEqual(doc, reconstructedDoc) @given(st.datetimes()) def test_datetimeToRTPTs(self, time): rtpTs = self.transmitter._datetimeToRTPTs(time) self.assertIsInstance(rtpTs, int) self.assertGreaterEqual(rtpTs, 0) self.assertLess(rtpTs, 2**32) @given( st.tuples(st.text(min_size=1), st.sampled_from(SUPPORTED_ENCODINGS), st.booleans(), st.integers(min_value=0, max_value=(2**32) - 1), st.booleans(), st.booleans()).filter( lambda x: len(utfEncode(x[0], x[1], x[2])) < 2**16)) def test_generateRTPPacket(self, data): doc, encoding, bom, time, isFirst, marker = data thisTransmitter = TTMLTransmitter("", 0, encoding=encoding, bom=bom) expectedSeqNum = thisTransmitter._nextSeqNum packet = thisTransmitter._generateRTPPacket(doc, time, isFirst, marker) payload = RTPPayload_TTML(encoding=encoding, bom=bom).fromBytearray(packet.payload) self.assertEqual(packet.timestamp, time) self.assertEqual(packet.sequenceNumber, expectedSeqNum) self.assertEqual(packet.marker, marker) self.assertEqual(payload.userDataWords, doc) self.assertEqual(thisTransmitter._nextSeqNum, expectedSeqNum + 1) @given( st.tuples(st.text(min_size=1), st.sampled_from(SUPPORTED_ENCODINGS), st.booleans(), st.datetimes(), st.booleans()).filter( lambda x: len(utfEncode(x[0], x[1], x[2])) < 2**16)) def test_packetiseDoc(self, data): doc, encoding, bom, time, marker = data thisTransmitter = TTMLTransmitter("", 0, encoding=encoding, bom=bom) expectedSeqNum = thisTransmitter._nextSeqNum packets = thisTransmitter._packetiseDoc(doc, time) for x in range(len(packets)): payload = RTPPayload_TTML( encoding=encoding, bom=bom).fromBytearray(packets[x].payload) self.assertEqual(packets[x].timestamp, thisTransmitter._datetimeToRTPTs(time)) self.assertEqual(packets[x].sequenceNumber, expectedSeqNum + x) self.assertIn(payload.userDataWords, doc) self.assertLess(len(utfEncode(payload.userDataWords)), 2**16) thisBom = BOMS[encoding] if bom and (x == 0): self.assertTrue(payload._userDataWords.startswith(thisBom)) else: self.assertFalse(payload._userDataWords.startswith(thisBom)) if x == (len(packets) - 1): self.assertTrue(packets[x].marker) else: self.assertFalse(packets[x].marker) self.assertEqual(thisTransmitter.nextSeqNum, expectedSeqNum + len(packets))
class TestExtension(TestCase): def setUp(self): self.thisP = RTPPayload_TTML() @given( st.tuples(st.text(), st.sampled_from(SUPPORTED_ENCODINGS), st.booleans()).filter( lambda x: len(utfEncode(x[0], x[1], x[2])) < 2**16)) def test_init(self, data): doc, encoding, bom = data reservedBits = bytearray(b'\x00\x00') newP = RTPPayload_TTML(reservedBits, doc, encoding, bom) self.assertEqual(newP.reserved, reservedBits) self.assertEqual(newP.userDataWords, doc) self.assertEqual(newP._encoding, encoding) self.assertEqual(newP._bom, bom) @given(st.text(), st.text().filter(lambda x: x not in SUPPORTED_ENCODINGS), st.booleans()) def test_init_invalidEnc(self, doc, enc, bom): reservedBits = bytearray(b'\x00\x00') with self.assertRaises(AttributeError): RTPPayload_TTML(reservedBits, doc, enc, bom) def test_reserved_default(self): self.assertEqual(self.thisP.reserved, bytearray(b'\x00\x00')) def test_reserved_notBytes(self): with self.assertRaises(AttributeError): self.thisP.reserved = "" @given(st.binary().filter(lambda x: x != bytearray(b'\x00\x00'))) def test_reserved_invalid(self, value): with self.assertRaises(ValueError): self.thisP.reserved = bytearray(value) def test_userDataWords_default(self): self.assertEqual(self.thisP.userDataWords, "") @given(st.text().filter(lambda x: len(utfEncode(x, "UTF-8")) < 2**16)) def test_userDataWords(self, doc): self.thisP.userDataWords = doc self.assertEqual(self.thisP.userDataWords, doc) def test_userDataWords_invalidType(self): with self.assertRaises(AttributeError): self.thisP.userDataWords = 0 def test_userDataWords_tooLong(self): doc = "" for x in range(2**16): doc += "a" with self.assertRaises(LengthError): self.thisP.userDataWords = doc @given( st.tuples(st.text(), st.sampled_from(SUPPORTED_ENCODINGS), st.booleans()).filter( lambda x: len(utfEncode(x[0], x[1], x[2])) < 2**16)) def test_userDataWords_encodings(self, data): doc, encoding, bom = data payload = RTPPayload_TTML(userDataWords=doc, encoding=encoding, bom=bom) self.assertEqual(payload.userDataWords, doc) self.assertEqual(payload._userDataWords, utfEncode(doc, encoding, bom)) def test_eq(self): reservedBits = bytearray(b'\x00\x00') newP = RTPPayload_TTML(reservedBits, "") self.assertEqual(newP, self.thisP) def test_bytearray_default(self): expected = bytearray(4) self.assertEqual(bytes(self.thisP), expected) newP = RTPPayload_TTML().fromBytearray(expected) self.assertEqual(newP, self.thisP) @given( st.binary(min_size=2, max_size=2).filter(lambda x: x != b'\x00\x00')) def test_fromBytearray_invalidLen(self, length): bArray = bytearray(4) bArray[2:4] = length with self.assertRaises(LengthError): RTPPayload_TTML().fromBytearray(bArray) @given(st.text()) def test_toBytearray(self, doc): self.thisP.userDataWords = doc bDoc = utfEncode(doc) expected = bytearray(2) expected += int(len(bDoc)).to_bytes(2, byteorder='big') expected += bDoc self.assertEqual(expected, self.thisP.toBytearray()) @given(st.text()) def test_fromBytearray(self, doc): expected = RTPPayload_TTML(userDataWords=doc) bDoc = utfEncode(doc) bArray = bytearray(2) bArray += int(len(bDoc)).to_bytes(2, byteorder='big') bArray += bDoc self.thisP.fromBytearray(bArray) self.assertEqual(expected, self.thisP)
def test_decode(self, data): doc, encoding, bom = data encoded = utfEncode(doc, encoding, bom) decoded = utfDecode(encoded, encoding) self.assertEqual(doc, decoded)
def test_encode_invalid(self, doc, enc, bom): with self.assertRaises(AttributeError): utfEncode(doc, enc, bom)
def test_encode_default(self, doc): ret = utfEncode(doc) self.assertEqual(ret, bytearray(doc, "utf_8"))