def test_acceptance(self): instance = RingBuffer(5) self.assertEqual(instance.write([1, 2, 3]), 3) self.assertEqual(instance.write([4, 5, 6]), 2) self.assertEqual(instance.read(), 1) self.assertEqual(instance.read(), 2) self.assertEqual(instance.read(), 3)
def test_read_works_after_several_writes(self): instance = RingBuffer(3) self.assertEqual(instance.write([1, 2]), 2) self.assertEqual(instance.read(), 1) self.assertEqual(instance.write([3, 4]), 2) self.assertEqual(instance.read(), 2) self.assertEqual(instance.write([5, 6]), 1) self.assertEqual(instance.read(), 3)
def test_basic_wrap(self): b = RingBuffer(4) b.write(b"ab") self.assertEqual(b.read(), b"ab") self.assertEqual(b.bytes_used(), 0) b.write(b"cde") self.assertEqual(b.read(), b"cd") self.assertEqual(b.read(), b"e") self.assertEqual(b.read(), None)
def test_size_wrap_and_full(self): b = RingBuffer(2) b.write(b"a") self.assertEqual(b.read(), b"a") self.assertEqual(b.read(), None) b.write(b"bc") self.assertEqual(b.read(), b"b") self.assertEqual(b.read(), b"c") self.assertEqual(b.read(), None)
def test_reading_exact_wrapping_full(self): b = RingBuffer(4) b.write(b"ab") self.assertEqual(b.read(), b"ab") b.write(b"defg") self.assertEqual(b.read_exactly(4), b"defg")
def test_reading_exact_wrapping_singles(self): b = RingBuffer(4) b.write(b"ab") self.assertEqual(b.read(), b"ab") b.write(b"defg") self.assertEqual(b.read_exactly(1), b"d") self.assertEqual(b.read_exactly(1), b"e") self.assertEqual(b.read_exactly(1), b"f")
def test_size_one_buffer(self): b = RingBuffer(1) self.assertEqual(b.bytes_total(), 1) self.assertEqual(b.bytes_free(), 1) self.assertEqual(b.bytes_used(), 0) b.write(b"a") self.assertEqual(b.bytes_total(), 1) self.assertEqual(b.bytes_free(), 0) self.assertEqual(b.bytes_used(), 1) self.assertEqual(b.read(), b"a") self.assertEqual(b.bytes_total(), 1) self.assertEqual(b.bytes_free(), 1) self.assertEqual(b.bytes_used(), 0) self.assertEqual(b.read(), None) b.write(b"b") self.assertEqual(b.read(), b"b") self.assertEqual(b.read(), None)
def test_read_return_first_element(self): instance = RingBuffer(5) instance.write([1, 2, 3, 4, 5]) actual = instance.read() self.assertEqual(actual, 1)
def test_read_raises_when_called_on_empty_buffer(self): instance = RingBuffer(5) with self.assertRaises(IndexError): instance.read()
sys.exit() # get the args in_file = sys.argv[1] sample_rate = int(sys.argv[2]) out_file = sys.argv[3] # calculate the delay to apply in samples delay = int(0.1 * sample_rate) # set up the ring buffer to implement the delay line buffer = RingBuffer(delay) with open(in_file, 'rb') as in_file_stream: with open(out_file, 'wb') as out_file_stream: left = in_file_stream.read(2) right = in_file_stream.read(2) while left and right: # allow left channel to pass through unchanged out_file_stream.write(left) # but delay the right channel buffer.write(struct.unpack('h', right)[0]) out_file_stream.write(struct.pack('h', buffer.read())) # perform the next read left = in_file_stream.read(2) right = in_file_stream.read(2) # ensure that the buffer empties before we're done for i in range(delay): out_file_stream.write(struct.pack('h', 0)) out_file_stream.write(struct.pack('h', buffer.read()))
def test_basic(self): b = RingBuffer(6) b.write(b"abc") self.assertEqual(b.read(), b"abc") self.assertEqual(b.read(), None)
def test_write_empty(self): b = RingBuffer(6) b.write(b"") self.assertEqual(b.bytes_used(), 0) self.assertEqual(b.read(), None)
def test_read_empty(self): b = RingBuffer(6) self.assertEqual(b.read(), None)
def test_random_operations(self): """A quicktest-lite test to verify various operations work as intended""" debug_this = False for test_num in range(1000): inputs = itertools.cycle(string.ascii_letters.encode("ascii")) # params for test operation_count = random.randrange(1, 20) # possible operations: None = read input, number = write that many bytes operations = random.choices([None] + list(range(1, 5)), k=operation_count) buffer_size = random.randrange(20) # do the test buffer = RingBuffer(buffer_size) read_from_buffer = bytearray() backup = bytearray() read_from_backup = bytearray() for op_i, op in enumerate(operations): try: if debug_this: print("doing op", op) if op is None: # slurp all items from buffer while True: last_read = buffer.read() if debug_this: print("read from buffer", last_read) if last_read is None: break else: read_from_buffer.extend(last_read) # slurp all items from backup read_from_backup.extend(backup) backup.clear() else: # check we can't write more than we have space for if len(backup) + op > buffer_size: with self.assertRaises(ValueError): items_to_write = list( itertools.islice(inputs, op)) buffer.write(items_to_write) # actually try and write no more than we have space for count_to_write = min(op, buffer_size - len(backup)) items_to_write = bytes( list(itertools.islice(inputs, count_to_write))) if debug_this: print("to_write", items_to_write) buffer.write(items_to_write) backup.extend(items_to_write) if debug_this: print("buffer:", buffer) self.assertEqual(read_from_buffer, read_from_backup) except AssertionError as e: message = e.args[0] message += "\nFailed on test number {}".format(test_num) message += "\nOperation: #{op_i} ('{op}')".format( op_i=op_i, op=op) message += "\nParams:\n\toperations={operations}\n\tbuffer_size={buffer_size}".format( operations=operations, buffer_size=buffer_size) message += "\nState:\n\tbuffer={buffer}\n\tbackup={backup}".format( buffer=buffer, backup=backup) e.args = (message, ) raise
class Messenger(object): def __init__(self, socket): self.socket = socket self._read_buffer = RingBuffer(2**20) self._send_buffer = RingBuffer(2**20) self._parser = MessageReader() def debug(self, s): print("Messenger{}: {}".format(self.socket.getpeername(), s)) def read_messages(self): """Call this you when know there is readable data for this socket; it will yield a tuple in the format of (transaction_id, message object) for each message that has been received.""" bytes_read = self.socket.recv(2048) if len(bytes_read) == 0: raise MessengerConnectionBroken("Socket connection broken", self.socket) self.debug("read {} bytes".format(len(bytes_read))) try: self._read_buffer.write(bytes_read) except ValueError: raise MessengerBufferFullError( "Failed to read message because read buffer is full", self.socket) while True: parsed = self._parser.try_parse(self._read_buffer) if parsed is None: return else: (tid, message) = parsed self.debug("received message; tid: {} message: {}".format( tid, message)) yield tid, message def queue_message(self, tid, message): """An API for queuing messages for sending later""" self.debug("queuing message; tid: {} message: {}".format( tid, message)) data = bson.dumps(message) header = struct.pack(MSG_HEADER_FMT, tid, len(data)) try: self._send_buffer.write(header) self._send_buffer.write(data) except ValueError: MessengerBufferFullError( "Failed to enqueue message because send buffer is full", self.socket) def has_messages_to_send(self): """Returns true if a message was previously queued but has not yet been sent""" return self._send_buffer.bytes_used() > 0 def send_messages(self): """Call this to actually send messages previous queued""" while True: to_send = self._send_buffer.read() if to_send is None: break self.debug("sending {} bytes".format(len(to_send))) message_length = len(to_send) bytes_sent_total = 0 while bytes_sent_total < message_length: sent = self.socket.send(to_send[bytes_sent_total:]) if sent == 0: raise MessengerConnectionBroken( "error sending, probably socket connection broke", self.socket) bytes_sent_total += sent