Esempio n. 1
0
    def test_field_decimal(self):
        w = Writer()
        w._field_decimal(Decimal('1.50'))
        assert_equals('D\x02\x00\x00\x00\x96', w._output_buffer)

        w = Writer()
        w._field_decimal(Decimal('-1.50'))
        assert_equals('D\x02\xff\xff\xff\x6a', w._output_buffer)
Esempio n. 2
0
    def test_write_bits(self):
        w = Writer()
        assert_true(w is w.write_bits(False, True))
        assert_equals(bytearray('\x02'), w._output_buffer)
        w = Writer()
        assert_true(w is w.write_bits(False, False, True, True, True))
        assert_equals(bytearray('\x1c'), w._output_buffer)

        assert_raises(ValueError, w.write_bits, *((True, ) * 9))
Esempio n. 3
0
    def test_write_shortstr(self):
        w = Writer()
        assert_true(w is w.write_shortstr(''))
        assert_equals(bytearray('\x00'), w._output_buffer)
        w = Writer()
        assert_true(w is w.write_shortstr('a' * 255))
        assert_equals(bytearray('\xff' + ('a' * 255)), w._output_buffer)
        w = Writer()
        assert_true(w is w.write_shortstr('Au\xc3\x9ferdem'.decode('utf8')))
        assert_equals(bytearray('\x09Au\xc3\x9ferdem'), w._output_buffer)

        assert_raises(ValueError, w.write_shortstr, 'a' * 256)
Esempio n. 4
0
    def test_parse_slow_for_standard_properties(self):
        HeaderFrame.DEFAULT_PROPERTIES = False
        bit_writer = Writer()
        val_writer = Writer()

        # strip ms because amqp doesn't include it
        now = datetime.utcfromtimestamp(
            long(time.mktime(datetime.now().timetuple())))

        bit_field = 0
        for pname, ptype, reader, writer, mask in HeaderFrame.PROPERTIES:
            bit_field = (bit_field << 1) | 1

            if ptype == 'shortstr':
                val_writer.write_shortstr(pname)
            elif ptype == 'octet':
                val_writer.write_octet(42)
            elif ptype == 'timestamp':
                val_writer.write_timestamp(now)
            elif ptype == 'table':
                val_writer.write_table({'foo': 'bar'})

        bit_field <<= (16 - len(HeaderFrame.PROPERTIES))
        bit_writer.write_short(bit_field)

        header_writer = Writer()
        header_writer.write_short(5)
        header_writer.write_short(6)
        header_writer.write_longlong(7)
        payload = header_writer.buffer()
        payload += bit_writer.buffer()
        payload += val_writer.buffer()

        reader = Reader(payload)
        frame = HeaderFrame.parse(4, reader)
        HeaderFrame.DEFAULT_PROPERTIES = True

        for pname, ptype, reader, writer, mask in HeaderFrame.PROPERTIES:
            if ptype == 'shortstr':
                self.assertEquals(pname, frame.properties[pname])
            elif ptype == 'octet':
                self.assertEquals(42, frame.properties[pname])
            elif ptype == 'timestamp':
                self.assertEquals(now, frame.properties[pname])
            elif ptype == 'table':
                self.assertEquals({'foo': 'bar'}, frame.properties[pname])

        assert_equals(4, frame.channel_id)
        assert_equals(5, frame._class_id)
        assert_equals(6, frame._weight)
        assert_equals(7, frame._size)
Esempio n. 5
0
 def test_write_longstr(self):
     # We can't actually build a string 2**32 long, so can't also test the
     # valueerror without mocking
     w = Writer()
     assert_true(w is w.write_longstr(''))
     assert_equals(bytearray('\x00\x00\x00\x00'), w._output_buffer)
     w = Writer()
     assert_true(w is w.write_longstr('a' * (2**16)))
     assert_equals(bytearray('\x00\x01\x00\x00' + ('a' * 2**16)),
                   w._output_buffer)
     w = Writer()
     assert_true(w is w.write_longstr('Au\xc3\x9ferdem'.decode('utf8')))
     assert_equals(bytearray('\x00\x00\x00\x09Au\xc3\x9ferdem'),
                   w._output_buffer)
Esempio n. 6
0
    def bind(self,
             queue,
             exchange,
             routing_key='',
             nowait=True,
             arguments={},
             ticket=None,
             cb=None):
        '''
    bind to a queue.
    '''
        nowait = nowait and self.allow_nowait() and not cb

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
          write_shortstr(queue).\
          write_shortstr(exchange).\
          write_shortstr(routing_key).\
          write_bit(nowait).\
          write_table(arguments)
        self.send_frame(MethodFrame(self.channel_id, 50, 20, args))

        if not nowait:
            self._bind_cb.append(cb)
            self.channel.add_synchronous_cb(self._recv_bind_ok)
Esempio n. 7
0
    def declare(self,
                queue='',
                passive=False,
                durable=False,
                exclusive=False,
                auto_delete=True,
                nowait=True,
                arguments={},
                ticket=None,
                cb=None):
        '''
    Declare a queue.  By default is asynchronoous but will be synchronous if nowait=False
    or a callback is defined. In synchronous mode, returns (message_count, consumer_count)

    queue - The name of the queue
    cb - An optional method which will be called with (queue_name, msg_count, consumer_count)
         if nowait=False
    '''
        nowait = nowait and self.allow_nowait() and not cb

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
          write_shortstr(queue).\
          write_bits(passive, durable, exclusive, auto_delete, nowait).\
          write_table(arguments)
        self.send_frame(MethodFrame(self.channel_id, 50, 10, args))

        if not nowait:
            self._declare_cb.append(cb)
            return self.channel.add_synchronous_cb(self._recv_declare_ok)
Esempio n. 8
0
  def cancel(self, consumer_tag='', nowait=True, consumer=None, cb=None):
    '''
    Cancel a consumer. Can choose to delete based on a consumer tag or the
    function which is consuming.  If deleting by function, take care to only
    use a consumer once per channel.
    '''
    if consumer:
      for (tag,func) in self._consumer_cb.iteritems():
        if func==consumer:
          consumer_tag = tag
          break

    nowait = nowait and self.allow_nowait() and not cb

    args = Writer()
    args.write_shortstr(consumer_tag).\
      write_bit(nowait)
    self.send_frame( MethodFrame(self.channel_id, 60, 30, args) )

    if not nowait:
      self._cancel_cb.append( cb )
      self.channel.add_synchronous_cb( self._recv_cancel_ok )
    else:
      try:
        del self._consumer_cb[consumer_tag]
      except KeyError:
        self.logger.warning( 'no callback registered for consumer tag " %s "', consumer_tag )
Esempio n. 9
0
    def test_write_field_supports_subclasses(self):
        class SubString(str):
            pass

        w = Writer()
        w._write_field(SubString('foo'))
        assert_equals('S\x00\x00\x00\x03foo', w._output_buffer)
Esempio n. 10
0
    def close(self, reply_code=0, reply_text='', class_id=0, method_id=0):
        '''
    Close this channel.  Caller has the option of specifying the reason for
    closure and the class and method ids of the current frame in which an error
    occurred.  If in the event of an exception, the channel will be marked
    as immediately closed.  If channel is already closed, call is ignored.
    '''
        if not getattr(self, 'channel', None) or self.channel._closed: return

        self.channel._close_info = {
            'reply_code': reply_code,
            'reply_text': reply_text,
            'class_id': class_id,
            'method_id': method_id
        }

        # exceptions here likely due to race condition as connection is closing
        # cap the reply_text we send because it may be arbitrarily long
        try:
            args = Writer()
            args.write_short(reply_code)
            args.write_shortstr(reply_text[:255])
            args.write_short(class_id)
            args.write_short(method_id)
            self.send_frame(MethodFrame(self.channel_id, 20, 40, args))

            self.channel.add_synchronous_cb(self._recv_close_ok)
        finally:
            # Immediately set the closed flag so that no more frames can be sent
            # NOTE: in synchronous mode, by the time this is called we will have
            # already run self.channel._closed_cb and so the channel reference is
            # gone.
            if self.channel:
                self.channel._closed = True
Esempio n. 11
0
    def write_frame(self, buf):
        writer = Writer(buf)
        writer.write_octet(self.type())
        writer.write_short(self.channel_id)

        # Write a temporary value for the total length of the frame
        stream_args_len_pos = len(buf)
        writer.write_long(0)

        # Mark the point in the stream where we start writing arguments,
        # *including* the class and method ids.
        stream_method_pos = len(buf)

        writer.write_short(self.class_id)
        writer.write_short(self.method_id)

        # This is assuming that args is a Writer
        if self._args is not None:
            writer.write(self._args.buffer())

        # Write the total length back at the position we allocated
        stream_len = len(buf) - stream_method_pos
        writer.write_long_at(stream_len, stream_args_len_pos)

        # Write the footer
        writer.write_octet(0xce)
Esempio n. 12
0
    def bind(self,
             queue,
             exchange,
             routing_key='',
             nowait=True,
             arguments={},
             ticket=None,
             cb=None):
        '''
    bind to a queue.
    '''
        # If a callback is defined, then we have to use synchronous transactions.
        if cb: nowait = False

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
          write_shortstr(queue).\
          write_shortstr(exchange).\
          write_shortstr(routing_key).\
          write_bit(nowait).\
          write_table(arguments)
        self.send_frame(MethodFrame(self.channel_id, 50, 20, args))

        if not nowait:
            self.channel.add_synchronous_cb(self._recv_bind_ok)
            self._bind_cb.append(cb)
Esempio n. 13
0
  def close(self, reply_code=0, reply_text='', class_id=0, method_id=0):
    '''
    Close this channel.  Caller has the option of specifying the reason for
    closure and the class and method ids of the current frame in which an error
    occurred.  If in the event of an exception, the channel will be marked
    as immediately closed.  If channel is already closed, call is ignored.
    '''
    if self._closed: return

    self._close_info = {
      'reply_code'    : reply_code,
      'reply_text'    : reply_text,
      'class_id'      : class_id,
      'method_id'     : method_id
    }

    # exception likely due to race condition as connection is closing
    try:
      args = Writer()
      args.write_short( reply_code )
      args.write_shortstr( reply_text )
      args.write_short( class_id )
      args.write_short( method_id )
      self.send_frame( MethodFrame(self.channel_id, 20, 40, args) )
      
      self.channel.add_synchronous_cb( self._recv_close_ok )
    except:
      self.logger.error("Failed to close channel %d", 
        self.channel_id, exc_info=True)

    # Immediately set the closed flag so that no more frames can be sent
    self._closed = True
Esempio n. 14
0
    def consume(self,
                queue,
                consumer,
                consumer_tag='',
                no_local=False,
                no_ack=True,
                exclusive=False,
                nowait=True,
                ticket=None,
                cb=None):
        '''
    Start a queue consumer. If `cb` is supplied, will be called when
    broker confirms that consumer is registered.
    '''
        nowait = nowait and self.allow_nowait() and not cb

        if nowait and consumer_tag == '':
            consumer_tag = self._generate_consumer_tag()

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
          write_shortstr(queue).\
          write_shortstr(consumer_tag).\
          write_bits( no_local, no_ack, exclusive, nowait ).\
          write_table({}) # unused according to spec
        self.send_frame(MethodFrame(self.channel_id, 60, 20, args))

        if not nowait:
            self._pending_consumers.append((consumer, cb))
            self.channel.add_synchronous_cb(self._recv_consume_ok)
        else:
            self._consumer_cb[consumer_tag] = consumer
Esempio n. 15
0
    def consume(self,
                queue,
                consumer,
                consumer_tag='',
                no_local=False,
                no_ack=True,
                exclusive=False,
                nowait=True,
                ticket=None):
        '''
    start a queue consumer.
    '''
        if nowait and consumer_tag == '':
            consumer_tag = self._generate_consumer_tag()

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
          write_shortstr(queue).\
          write_shortstr(consumer_tag).\
          write_bits( no_local, no_ack, exclusive, nowait ).\
          write_table({}) # unused according to spec
        self.send_frame(MethodFrame(self.channel_id, 60, 20, args))

        if not nowait:
            self.channel.add_synchronous_cb(self._recv_consume_ok)
            self._pending_consumers.append(consumer)
        else:
            self._consumer_cb[consumer_tag] = consumer
Esempio n. 16
0
 def _send_close(self):
     args = Writer()
     args.write_short(self.connection._close_info['reply_code'])
     args.write_shortstr(self.connection._close_info['reply_text'][:255])
     args.write_short(self.connection._close_info['class_id'])
     args.write_short(self.connection._close_info['method_id'])
     self.send_frame(MethodFrame(self.channel_id, 10, 50, args))
Esempio n. 17
0
    def unbind(self,
               exchange,
               source,
               routing_key='',
               nowait=True,
               arguments={},
               ticket=None,
               cb=None):
        '''
    Unbind an exchange from another.
    '''
        nowait = nowait and self.allow_nowait() and not cb

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
          write_shortstr(exchange).\
          write_shortstr(source).\
          write_shortstr(routing_key).\
          write_bit(nowait).\
          write_table(arguments or {})
        self.send_frame(MethodFrame(self.channel_id, 40, 40, args))

        if not nowait:
            self._unbind_cb.append(cb)
            self.channel.add_synchronous_cb(self._recv_unbind_ok)
Esempio n. 18
0
    def nack(self, delivery_tag, multiple=False, requeue=False):
        '''Send a nack to the broker.'''
        args = Writer()
        args.write_longlong(delivery_tag).\
          write_bits(multiple, requeue)

        self.send_frame(MethodFrame(self.channel_id, 60, 120, args))
Esempio n. 19
0
    def _send_open(self):
        args = Writer()
        args.write_shortstr(self.connection._vhost)
        args.write_shortstr('')
        args.write_bit(True)  # insist flag for older amqp, not used in 0.9.1

        self.send_frame(MethodFrame(self.channel_id, 10, 40, args))
Esempio n. 20
0
    def declare(self,
                exchange,
                type,
                passive=False,
                durable=False,
                nowait=True,
                arguments=None,
                ticket=None,
                cb=None):
        """
        Declare the exchange.

        exchange - The name of the exchange to declare
        type - One of
        """
        nowait = nowait and self.allow_nowait() and not cb

        args = Writer()
        args.write_short(ticket or self.default_ticket).\
            write_shortstr(exchange).\
            write_shortstr(type).\
            write_bits(passive, durable, False, False, nowait).\
            write_table(arguments or {})
        self.send_frame(MethodFrame(self.channel_id, 40, 10, args))

        if not nowait:
            self._declare_cb.append(cb)
            self.channel.add_synchronous_cb(self._recv_declare_ok)
Esempio n. 21
0
    def test_field_table(self):
        w = Writer()
        expect(w.write_table).args({'foo': 'bar'}).side_effect(
            lambda *args: w._output_buffer.extend('tdata'))
        w._field_table({'foo': 'bar'})

        assert_equals('Ftdata', w._output_buffer)
Esempio n. 22
0
    def test_write_short_at(self):
        w = Writer(bytearray('\x00' * 6))
        assert_true(w is w.write_short_at(2**16 - 1, 2))
        assert_equals(bytearray('\x00\x00\xff\xff\x00\x00'), w._output_buffer)

        assert_raises(ValueError, w.write_short_at, -1, 2)
        assert_raises(ValueError, w.write_short_at, 2**16, 3)
Esempio n. 23
0
    def write_frame(self, buf):
        '''
        Write the frame into an existing buffer.
        '''
        writer = Writer(buf)
        writer.write_octet(self.type())
        writer.write_short(self.channel_id)

        # Track the position where we're going to write the total length
        # of the frame arguments.
        stream_args_len_pos = len(buf)
        writer.write_long(0)

        stream_method_pos = len(buf)

        writer.write_short(self._class_id)
        writer.write_short(self._weight)
        writer.write_longlong(self._size)

        # Like frame parsing, branch to faster code for default properties
        if self.DEFAULT_PROPERTIES:
            # Track the position where we're going to write the flags.
            flags_pos = len(buf)
            writer.write_short(0)
            flag_bits = 0
            for key, proptype, rfunc, wfunc, mask in self.PROPERTIES:
                val = self._properties.get(key, None)
                if val is not None:
                    flag_bits |= mask
                    wfunc(writer, val)
            writer.write_short_at(flag_bits, flags_pos)
        else:
            shift = 15
            flag_bits = 0
            flags = []
            stack = deque()
            for key, proptype, rfunc, wfunc, mask in self.PROPERTIES:
                val = self._properties.get(key, None)
                if val is not None:
                    if shift == 0:
                        flags.append(flag_bits)
                        flag_bits = 0
                        shift = 15

                    flag_bits |= (1 << shift)
                    stack.append((wfunc, val))

                shift -= 1

            flags.append(flag_bits)
            for flag_bits in flags:
                writer.write_short(flag_bits)
            for method, val in stack:
                method(writer, val)

        # Write the total length back at the beginning of the frame
        stream_len = len(buf) - stream_method_pos
        writer.write_long_at(stream_len, stream_args_len_pos)

        writer.write_octet(0xce)
Esempio n. 24
0
 def _send_flow(self, active):
     '''
     Send a flow control command.
     '''
     args = Writer()
     args.write_bit(active)
     self.send_frame(MethodFrame(self.channel_id, 20, 20, args))
     self.channel.add_synchronous_cb(self._recv_flow_ok)
Esempio n. 25
0
 def open(self):
     '''
     Open the channel for communication.
     '''
     args = Writer()
     args.write_shortstr('')
     self.send_frame(MethodFrame(self.channel_id, 20, 10, args))
     self.channel.add_synchronous_cb(self._recv_open_ok)
Esempio n. 26
0
    def test_write_short(self):
        w = Writer()
        assert_true(w is w.write_short(0))
        assert_true(w is w.write_short(2**16 - 2))
        assert_equals(bytearray('\x00\x00\xff\xfe'), w._output_buffer)

        assert_raises(ValueError, w.write_short, -1)
        assert_raises(ValueError, w.write_short, 2**16)
Esempio n. 27
0
    def test_write_octet(self):
        w = Writer()
        assert_true(w is w.write_octet(0))
        assert_true(w is w.write_octet(255))
        assert_equals(bytearray('\x00\xff'), w._output_buffer)

        assert_raises(ValueError, w.write_octet, -1)
        assert_raises(ValueError, w.write_octet, 2**8)
Esempio n. 28
0
 def _send_start_ok(self):
     '''Send the start_ok message.'''
     args = Writer()
     args.write_table(self.connection._properties)
     args.write_shortstr(self.connection._login_method)
     args.write_longstr(self.connection._login_response)
     args.write_shortstr(self.connection._locale)
     self.send_frame(MethodFrame(self.channel_id, 10, 11, args))
Esempio n. 29
0
    def test_field_int(self):
        w = Writer()
        w._field_int(-2**15)
        w._field_int(2**15 - 1)
        assert_equals('s\x80\x00s\x7f\xff', w._output_buffer)

        w = Writer()
        w._field_int(-2**31)
        w._field_int(2**31 - 1)
        assert_equals('I\x80\x00\x00\x00I\x7f\xff\xff\xff', w._output_buffer)

        w = Writer()
        w._field_int(-2**63)
        w._field_int(2**63 - 1)
        assert_equals(
            'l\x80\x00\x00\x00\x00\x00\x00\x00l\x7f\xff\xff\xff\xff\xff\xff\xff',
            w._output_buffer)
Esempio n. 30
0
    def test_write_long(self):
        w = Writer()
        assert_true(w is w.write_long(0))
        assert_true(w is w.write_long(2**32 - 2))
        assert_equals(bytearray('\x00\x00\x00\x00\xff\xff\xff\xfe'),
                      w._output_buffer)

        assert_raises(ValueError, w.write_long, -1)
        assert_raises(ValueError, w.write_long, 2**32)