Exemple #1
0
 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)
Exemple #2
0
 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)
Exemple #8
0
 def test_read_return_first_element(self):
     instance = RingBuffer(5)
     instance.write([1, 2, 3, 4, 5])
     actual = instance.read()
     self.assertEqual(actual, 1)
Exemple #9
0
 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