def test_closed_cb_without_final_frame(self): c = Channel('connection', None, { 20: ChannelClass, 40: ExchangeClass, 50: QueueClass, 60: BasicClass, 90: TransactionClass, }) c._pending_events = 'foo' c._frame_buffer = 'foo' for val in c._class_map.values(): expect(val._cleanup) expect(c._notify_close_listeners) c._closed_cb() assert_equals(deque([]), c._pending_events) assert_equals(deque([]), c._frame_buffer) assert_equals(None, c._connection) assert_false(hasattr(c, 'channel')) assert_false(hasattr(c, 'exchange')) assert_false(hasattr(c, 'queue')) assert_false(hasattr(c, 'basic')) assert_false(hasattr(c, 'tx')) assert_equals(None, c._class_map) assert_equals(set(), c._close_listeners)
def test_clear_synchronous_cb_when_pending_cb_doesnt_match_but_isnt_in_list(self): c = Channel(None, None, {}) stub(c._flush_pending_events) c._pending_events = deque(['foo', 'bar']) assert_raises(ChannelError, c.clear_synchronous_cb, 'bar') assert_equals(deque(['foo', 'bar']), c._pending_events)
def test_close_with_args(self): c = Channel(None, None, {}) expect(mock(c, 'channel').close).args(1, 'two', 3, 4) expect(c.channel.close).args(1, 'two', 3, 4) c.close(1, 'two', 3, 4) c.close(reply_code=1, reply_text='two', class_id=3, method_id=4)
def test_clear_synchronous_cb_when_pending_cb_doesnt_match_but_isnt_in_list(self): c = Channel(None,None,{}) stub( c._flush_pending_events ) c._pending_events = deque(['foo', 'bar']) assertRaises( ChannelError, c.clear_synchronous_cb, 'bar' ) assertEquals( deque(['foo','bar']), c._pending_events )
def test_next_frame_with_a_frame(self): c = Channel(None, None, {}) ch_id, c_id, m_id = 0, 1, 2 f0 = MethodFrame(ch_id, c_id, m_id) f1 = MethodFrame(ch_id, c_id, m_id) c._frame_buffer = deque([f0, f1]) assertEquals(c.next_frame(), f0)
def channel(self, channel_id=None): """ Fetch a Channel object identified by the numeric channel_id, or create that object if it doesn't already exist. If channel_id is not None but no channel exists for that id, will raise InvalidChannel. If there are already too many channels open, will raise TooManyChannels. """ if channel_id is None: # adjust for channel 0 if len(self._channels) - 1 >= self._channel_max: raise Connection.TooManyChannels( "%d channels already open, max %d", len(self._channels) - 1, self._channel_max) channel_id = self._next_channel_id() while channel_id in self._channels: channel_id = self._next_channel_id() elif channel_id in self._channels: return self._channels[channel_id] else: raise Connection.InvalidChannel("%s is not a valid channel id", channel_id) # Call open() here so that ConnectionChannel doesn't have it called. Could # also solve this other ways, but it's a HACK regardless. rval = Channel(self, channel_id) self._channels[channel_id] = rval rval.open() return rval
def test_init(self): connection = mock() c = Channel(connection, 'id', self._CLASS_MAP) assert_equals(connection, c._connection) assert_equals('id', c._channel_id) assert_true(isinstance(c.channel, ChannelClass)) assert_true(isinstance(c.exchange, ExchangeClass)) assert_true(isinstance(c.queue, QueueClass)) assert_true(isinstance(c.basic, BasicClass)) assert_true(isinstance(c.tx, TransactionClass)) assert_false(c._synchronous) assert_equals(c._class_map[20], c.channel) assert_equals(c._class_map[40], c.exchange) assert_equals(c._class_map[50], c.queue) assert_equals(c._class_map[60], c.basic) assert_equals(c._class_map[90], c.tx) assert_equals(deque([]), c._pending_events) assert_equals(deque([]), c._frame_buffer) assert_equals(set([]), c._open_listeners) assert_equals(set([]), c._close_listeners) assert_false(c._closed) assert_equals( { 'reply_code': 0, 'reply_text': 'first connect', 'class_id': 0, 'method_id': 0 }, c._close_info) assert_true(c._active) c = Channel(connection, 'id', self._CLASS_MAP, synchronous=True) assert_true(c._synchronous)
def test_send_frame_when_not_closed_no_flow_control_pending_event(self): conn = mock() c = Channel(conn, 32, {}) c._pending_events.append('cb') c.send_frame('frame') assert_equals(deque(['cb', 'frame']), c._pending_events)
def test_send_frame_when_closed_for_no_reason(self): conn = mock() c = Channel(conn, 32, {}) c._closed = True c._close_info = {"reply_code": 42, "reply_text": ""} assertRaises(ChannelClosed, c.send_frame, "frame")
def test_send_frame_when_not_closed_no_flow_control_pending_event(self): conn = mock() c = Channel(conn, 32, {}) c._pending_events.append("cb") c.send_frame("frame") self.assertEquals(deque(["cb", "frame"]), c._pending_events)
def test_publish_synchronous(self): c = Channel(None, None, {}) expect(mock(c, 'tx').select) expect(mock(c, 'basic').publish).args('arg1', 'arg2', foo='bar') expect(c.tx.commit).args(cb='a_cb') c.publish_synchronous('arg1', 'arg2', foo='bar', cb='a_cb')
def test_send_frame_when_not_closed_no_flow_control_no_pending_events(self): conn = mock() c = Channel(conn, 32, {}) expect( conn.send_frame ).args('frame') c.send_frame( 'frame' )
def test_send_frame_when_closed_for_no_reason(self): conn = mock() c = Channel(conn, 32, {}) c._closed = True c._close_info = {'reply_code': 42, 'reply_text': ''} assert_raises(ChannelClosed, c.send_frame, 'frame')
def test_send_frame_when_closed_for_no_reason(self): conn = mock() c = Channel(conn, 32, {}) c._closed = True c._close_info = {'reply_code': 42, 'reply_text': ''} assertRaises(ChannelClosed, c.send_frame, 'frame')
def dispatch(self, frame): ''' Override the default dispatch since we don't need the rest of the stack. ''' if frame.type() == HeartbeatFrame.type(): self.send_heartbeat() elif frame.type() == MethodFrame.type(): if frame.class_id == 10: cb = self._method_map.get(frame.method_id) if cb: cb(frame) else: raise Channel.InvalidMethod( "unsupported method %d on channel %d", frame.method_id, self.channel_id) else: raise Channel.InvalidClass( "class %d is not supported on channel %d", frame.class_id, self.channel_id) else: raise Frame.InvalidFrameType( "frame type %d is not supported on channel %d", frame.type(), self.channel_id)
def test_send_frame_when_not_closed_no_flow_control_pending_event(self): conn = mock() c = Channel(conn, 32, {}) c._pending_events.append('cb') c.send_frame('frame') self.assertEquals(deque(['cb', 'frame']), c._pending_events)
def test_next_frame_with_a_frame(self): c = Channel(None, None, {}) ch_id, c_id, m_id = 0, 1, 2 f0 = MethodFrame(ch_id, c_id, m_id) f1 = MethodFrame(ch_id, c_id, m_id) c._frame_buffer = deque([f0, f1]) assert_equals(c.next_frame(), f0)
def channel(self, channel_id=None, synchronous=False): """ Fetch a Channel object identified by the numeric channel_id, or create that object if it doesn't already exist. If channel_id is not None but no channel exists for that id, will raise InvalidChannel. If there are already too many channels open, will raise TooManyChannels. If synchronous=True, then the channel will act synchronous in all cases where a protocol method supports `nowait=False`, or where there is an implied callback in the protocol. """ if channel_id is None: # adjust for channel 0 if len(self._channels) - 1 >= self._channel_max: raise Connection.TooManyChannels( "%d channels already open, max %d", len(self._channels) - 1, self._channel_max) channel_id = self._next_channel_id() while channel_id in self._channels: channel_id = self._next_channel_id() elif channel_id in self._channels: return self._channels[channel_id] else: raise Connection.InvalidChannel("%s is not a valid channel id", channel_id) # Call open() here so that ConnectionChannel doesn't have it called. Could # also solve this other ways, but it's a HACK regardless. ch = Channel(self, channel_id, self._class_map, synchronous=synchronous) self._channels[channel_id] = ch ch.add_close_listener(self._channel_closed) ch.open() return ch
def channel(self, channel_id=None): """ Fetch a Channel object identified by the numeric channel_id, or create that object if it doesn't already exist. If channel_id is not None but no channel exists for that id, will raise InvalidChannel. If there are already too many channels open, will raise TooManyChannels. """ if channel_id is None: # adjust for channel 0 if len(self._channels)-1 >= self._channel_max: raise Connection.TooManyChannels( "%d channels already open, max %d", len(self._channels)-1, self._channel_max ) channel_id = self._next_channel_id() while channel_id in self._channels: channel_id = self._next_channel_id() elif channel_id in self._channels: return self._channels[channel_id] else: raise Connection.InvalidChannel("%s is not a valid channel id", channel_id ) # Call open() here so that ConnectionChannel doesn't have it called. Could # also solve this other ways, but it's a HACK regardless. rval = Channel(self, channel_id, self._class_map) self._channels[ channel_id ] = rval rval.add_close_listener( self._channel_closed ) rval.open() return rval
def test_publish_synchronous(self): c = Channel(None, None, {}) expect(mock(c, "tx").select) expect(mock(c, "basic").publish).args("arg1", "arg2", foo="bar") expect(c.tx.commit).args(cb="a_cb") c.publish_synchronous("arg1", "arg2", foo="bar", cb="a_cb")
def test_send_frame_when_not_closed_no_flow_control_no_pending_events(self): conn = mock() c = Channel(conn, 32, {}) expect(conn.send_frame).args('frame') c.send_frame('frame')
def test_clear_synchronous_cb_when_pending_cb_matches(self): c = Channel(None,None) c._pending_events = ['foo'] expect( c._flush_pending_events ) c.clear_synchronous_cb( 'foo' ) assertEquals( [], c._pending_events )
def test_notify_close_listeners(self): c = Channel(None, None, {}) cb1 = mock() cb2 = mock() c._close_listeners = set([cb1, cb2]) expect(cb1).args(c) expect(cb2).args(c) c._notify_close_listeners()
def test_requeue_frames(self): c = Channel(None, None, {}) ch_id, c_id, m_id = 0, 1, 2 f = [MethodFrame(ch_id, c_id, m_id) for i in xrange(4)] c._frame_buffer = deque(f[:2]) c.requeue_frames(f[2:]) assert_equals(c._frame_buffer, deque([f[i] for i in [3, 2, 0, 1]]))
def test_clear_synchronous_cb_when_pending_cb_doesnt_match_but_isnt_in_list(self): c = Channel(None,None) c._pending_events = ['foo'] expect( c._flush_pending_events ) c.clear_synchronous_cb( 'bar' ) assertEquals( ['foo'], c._pending_events )
def test_clear_synchronous_cb_when_pending_cb_matches(self): c = Channel(None, None) c._pending_events = ['foo'] expect(c._flush_pending_events) c.clear_synchronous_cb('foo') assertEquals([], c._pending_events)
def test_clear_synchronous_cb_when_pending_cb_matches(self): c = Channel(None, None, {}) c._pending_events = deque(['foo']) expect(c._flush_pending_events) assert_equals('foo', c.clear_synchronous_cb('foo')) assert_equals(deque([]), c._pending_events)
def test_requeue_frames(self): c = Channel(None, None, {}) ch_id, c_id, m_id = 0, 1, 2 f = [MethodFrame(ch_id, c_id, m_id) for i in xrange(4)] c._frame_buffer = deque(f[:2]) c.requeue_frames(f[2:]) assertEquals(c._frame_buffer, deque([f[i] for i in [3, 2, 0, 1]]))
def test_clear_synchronous_cb_when_pending_cb_doesnt_match_but_isnt_in_list(self): c = Channel(None,None,{}) c._pending_events = deque(['foo']) expect( c._flush_pending_events ) assert_equals( 'bar', c.clear_synchronous_cb('bar') ) assertEquals( deque(['foo']), c._pending_events )
def test_clear_synchronous_cb_when_pending_cb_doesnt_match_but_isnt_in_list(self): c = Channel(None, None, {}) c._pending_events = deque(['foo']) expect(c._flush_pending_events) assert_equals('bar', c.clear_synchronous_cb('bar')) assert_equals(deque(['foo']), c._pending_events)
def test_add_synchronous_cb_when_transport_asynchronous(self): conn = mock() conn.synchronous = False c = Channel(conn, None, {}) assert_equals(deque([]), c._pending_events) c.add_synchronous_cb('foo') assert_equals(deque(['foo']), c._pending_events)
def test_clear_synchronous_cb_when_pending_cb_matches(self): c = Channel(None, None, {}) c._pending_events = deque(['foo']) expect(c._flush_pending_events) assert_equals('foo', c.clear_synchronous_cb('foo')) assertEquals(deque([]), c._pending_events)
def test_add_synchronous_cb_when_transport_asynchronous(self): conn = mock() conn.synchronous = False c = Channel(conn, None, {}) assertEquals(deque([]), c._pending_events) c.add_synchronous_cb('foo') assertEquals(deque(['foo']), c._pending_events)
def test_closed_cb_with_final_frame(self): conn = mock() c = Channel(conn, None, {}) expect(conn.send_frame).args('final') for val in c._class_map.values(): expect(val._cleanup) c._closed_cb('final')
def test_clear_synchronous_cb_when_pending_cb_doesnt_match_but_isnt_in_list( self): c = Channel(None, None) c._pending_events = ['foo'] expect(c._flush_pending_events) c.clear_synchronous_cb('bar') assertEquals(['foo'], c._pending_events)
def test_process_frames_stops_when_buffer_is_empty(self): c = Channel(None, None) f0 = MethodFrame('ch_id', 'c_id', 'm_id') f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([ f0, f1 ]) expect( c.dispatch ).args( f0 ) expect( c.dispatch ).args( f1 ) c.process_frames()
def test_process_frames_stops_when_frameunderflow_raised(self): c = Channel(None, None, {}) f0 = MethodFrame('ch_id', 'c_id', 'm_id') f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(ProtocolClass.FrameUnderflow) c.process_frames() assertEquals(f1, c._frame_buffer[0])
def test_process_frames_stops_when_buffer_is_empty(self): c = Channel(None, None) f0 = MethodFrame('ch_id', 'c_id', 'm_id') f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0) expect(c.dispatch).args(f1) c.process_frames()
def test_process_frames_stops_when_frameunderflow_raised(self): c = Channel(None, None, {}) f0 = MethodFrame('ch_id', 'c_id', 'm_id') f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(ProtocolClass.FrameUnderflow) c.process_frames() assert_equals(f1, c._frame_buffer[0])
def test_process_frames_with_one_frame(self): conn = mock() conn.logger = mock() c = Channel(conn, None) ch_id, c_id, m_id = 0, 20, 2 f = MethodFrame(ch_id, c_id, m_id) c._frame_buffer = deque([ f ]) expect(c.logger.error).args(ignore(), ignore(), exc_info=ignore()) expect(c.close).args(ignore(), ignore()) c.process_frames()
def test_process_frames_stops_when_buffer_is_empty(self): c = Channel(None, None, {}) f0 = MethodFrame("ch_id", "c_id", "m_id") f1 = MethodFrame("ch_id", "c_id", "m_id") c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0) expect(c.dispatch).args(f1) c.process_frames() assert_equals(deque(), c._frame_buffer)
def test_process_frames_with_one_frame(self): conn = mock() conn.logger = mock() c = Channel(conn, None) ch_id, c_id, m_id = 0, 20, 2 f = MethodFrame(ch_id, c_id, m_id) c._frame_buffer = deque([f]) expect(c.logger.error).args(ignore(), ignore(), exc_info=ignore()) expect(c.close).args(ignore(), ignore()) c.process_frames()
def test_dispatch(self): c = Channel(None, None, {}) frame = mock() frame.class_id = 32 klass = mock() c._class_map[32] = klass expect(klass.dispatch).args(frame) c.dispatch(frame) frame.class_id = 33 assert_raises(Channel.InvalidClass, c.dispatch, frame)
def test_flush_pending_events_flushes_all_leading_frames(self): conn = mock() c = Channel(conn, 42, {}) f1 = MethodFrame(1, 2, 3) f2 = MethodFrame(1, 2, 3) f3 = MethodFrame(1, 2, 3) c._pending_events = deque([f1, f2, 'cb', f3]) expect(conn.send_frame).args(f1) expect(conn.send_frame).args(f2) c._flush_pending_events() assert_equals(deque(['cb', f3]), c._pending_events)
def test_flush_pending_events_flushes_all_leading_frames(self): conn = mock() c = Channel(conn, 42, {}) f1 = MethodFrame(1, 2, 3) f2 = MethodFrame(1, 2, 3) f3 = MethodFrame(1, 2, 3) c._pending_events = deque([f1, f2, 'cb', f3]) expect(conn.send_frame).args(f1) expect(conn.send_frame).args(f2) c._flush_pending_events() assertEquals(deque(['cb', f3]), c._pending_events)
def test_process_frames_when_connectionclosed_on_dispatch(self): c = Channel(None, None, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(ConnectionClosed('something darkside')) stub(c.close) # assert not called assert_raises(ConnectionClosed, c.process_frames)
def test_process_frames_when_connectionclosed_on_dispatch(self): c = Channel(None, None, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises( ConnectionClosed('something darkside')) stub(c.close) # assert not called assert_raises(ConnectionClosed, c.process_frames)
def test_process_frames_logs_and_closes_when_systemexit_raised(self): c = Channel(None, None, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(SystemExit()) stub(c.close) assert_raises(SystemExit, c.process_frames) assert_equals(f1, c._frame_buffer[0])
def test_process_frames_logs_and_closes_when_dispatch_error_raised_even_when_exception_on_close(self): c = Channel(None, None, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(RuntimeError("zomg it broked")) expect(c.close).raises(ValueError()) assert_raises(RuntimeError, c.process_frames) assert_equals(f1, c._frame_buffer[0])
def test_process_frames_logs_and_closes_when_dispatch_error_raised(self): c = Channel(None, None, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(RuntimeError("zomg it broked")) expect(c.close).args(500, 'Failed to dispatch %s' % (str(f0))) assert_raises(RuntimeError, c.process_frames) assertEquals(f1, c._frame_buffer[0])
def test_process_frames_logs_and_closes_when_systemexit_raised(self): c = Channel(None, None, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(SystemExit()) stub(c.close) assert_raises(SystemExit, c.process_frames) assertEquals(f1, c._frame_buffer[0])
def test_properties(self): connection = mock() connection.logger = 'logger' c = Channel(connection, 'id') c.channel = mock() c.channel.closed = 'closed' c.channel.close_info = 'uwerebad' assertEquals(connection, c.connection) assertEquals('id', c.channel_id) assertEquals('logger', c.logger) assertEquals('closed', c.closed) assertEquals('uwerebad', c.close_info)
def test_init(self): c = Channel( 'connection', 'id', { 20: ChannelClass, 40: ExchangeClass, 50: QueueClass, 60: BasicClass, 90: TransactionClass, }) self.assertEquals('connection', c._connection) self.assertEquals('id', c._channel_id) self.assertTrue(isinstance(c.channel, ChannelClass)) self.assertTrue(isinstance(c.exchange, ExchangeClass)) self.assertTrue(isinstance(c.queue, QueueClass)) self.assertTrue(isinstance(c.basic, BasicClass)) self.assertTrue(isinstance(c.tx, TransactionClass)) self.assertEquals(c._class_map[20], c.channel) self.assertEquals(c._class_map[40], c.exchange) self.assertEquals(c._class_map[50], c.queue) self.assertEquals(c._class_map[60], c.basic) self.assertEquals(c._class_map[90], c.tx) self.assertEquals(deque([]), c._pending_events) self.assertEquals(deque([]), c._frame_buffer) assert_equals(set([]), c._open_listeners) assert_equals(set([]), c._close_listeners) assert_false(c._closed) assert_equals( { 'reply_code': 0, 'reply_text': 'first connect', 'class_id': 0, 'method_id': 0 }, c._close_info) assert_true(c._active)
def test_add_synchronous_cb_when_transport_synchronous_and_channel_closes(self): conn = mock() conn.synchronous = True c = Channel(conn,None,{}) wrapper = mock() wrapper._read = True wrapper._result = 'done' expect( channel.SyncWrapper ).args( 'foo' ).returns( wrapper ) expect( conn.read_frames ) expect( conn.read_frames ).side_effect( lambda: setattr(c, '_closed', True) ) with assert_raises( ChannelClosed ): c.add_synchronous_cb('foo')
def test_process_frames_raises_systemexit_when_close_raises_systemexit(self): c = Channel(mock(), 20, {}) c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(20, 30, 40) f1 = MethodFrame('ch_id', 'c_id', 'm_id') c._frame_buffer = deque([f0, f1]) expect(c.dispatch).args(f0).raises(RuntimeError("zomg it broked")) expect(c.logger.exception).args( 'Closing on failed dispatch of frame %.255s', f0) expect(c.close).raises(SystemExit()) assert_raises(SystemExit, c.process_frames) assert_equals(f1, c._frame_buffer[0])
def test_process_frames_drops_non_close_methods_when_emergency_closing( self): c = Channel(mock(), None, self._CLASS_MAP) c._emergency_close_pending = True c._connection = mock() c._connection.logger = mock() f0 = MethodFrame(1, 30, 40) f1 = HeaderFrame(1, 30, 0, 0) f2 = ContentFrame(1, "payload") f3_basic_close = MethodFrame(1, 20, 40) f4_basic_close_ok = MethodFrame(1, 20, 41) f5 = MethodFrame(1, 90, 11) c._frame_buffer = deque( [f0, f1, f2, f3_basic_close, f4_basic_close_ok, f5]) expect(c.dispatch).args(f0).times(0) expect(c.dispatch).args(f1).times(0) expect(c.dispatch).args(f2).times(0) expect(c.dispatch).args(f3_basic_close).times(1) expect(c.dispatch).args(f4_basic_close_ok).times(1) expect(c.dispatch).args(f5).times(0) expect(c.logger.warn).times(4) c.process_frames() assert_equals(0, len(c._frame_buffer))