Merge with default
This commit is contained in:
		
						commit
						29699ea26a
					
				|  | @ -7,8 +7,6 @@ TEST_APPS=rabbit_stomp | ||||||
| TEST_SCRIPTS=./test/test.py | TEST_SCRIPTS=./test/test.py | ||||||
| UNIT_TEST_COMMANDS=eunit:test([rabbit_stomp_test_util,rabbit_stomp_test_frame],[verbose]) | UNIT_TEST_COMMANDS=eunit:test([rabbit_stomp_test_util,rabbit_stomp_test_frame],[verbose]) | ||||||
| 
 | 
 | ||||||
| TEST_ARGS=-rabbit_stomp listeners "[{\"0.0.0.0\",61613}]" |  | ||||||
| 
 |  | ||||||
| include ../include.mk | include ../include.mk | ||||||
| 
 | 
 | ||||||
| testdeps: | testdeps: | ||||||
|  |  | ||||||
|  | @ -32,21 +32,26 @@ You need to install the rabbit\_stomp.ez and amqp\_client.ez packages. | ||||||
| 
 | 
 | ||||||
| ## Running the STOMP adapter | ## Running the STOMP adapter | ||||||
| 
 | 
 | ||||||
| ### Configuring the server to start the plugin automatically | When no configuration is specified the STOMP Adapter will listen on | ||||||
|  | all interfaces on port 61613. | ||||||
| 
 | 
 | ||||||
| Most RabbitMQ server packages are set up to cause the server to pick | To change this, edit your [Configuration file](http://www.rabbitmq.com/install.html#configfile), | ||||||
| up configuration from `/etc/rabbitmq/rabbitmq.conf`. To tell the | to contain a tcp_listeners variable for the rabbit_stomp application. | ||||||
| server to start your plugin, first make sure it is compiled, and then |  | ||||||
| add the following text to `/etc/rabbitmq/rabbitmq.conf`: |  | ||||||
| 
 | 
 | ||||||
|     SERVER_START_ARGS='-rabbit_stomp listeners [{"0.0.0.0",61613}]' | For example, a complete configuration file which changes the listener | ||||||
|  | port to 12345 would look like: | ||||||
| 
 | 
 | ||||||
| Then restart the server with | [ | ||||||
|  |   {rabbit_stomp, [{tcp_listeners, [12345]} ]} | ||||||
|  | ]. | ||||||
| 
 | 
 | ||||||
|     sudo /etc/init.d/rabbitmq-server restart | while one which changes the listener to listen only on localhost (for | ||||||
|  | both IPv4 and IPv6) would look like: | ||||||
| 
 | 
 | ||||||
| When no configuration is specified the STOMP Adapter will listen on  | [ | ||||||
| localhost by default. |   {rabbit_stomp, [{tcp_listeners, [{"127.0.0.1", 61613}, | ||||||
|  |                                    {"::1",       61613} ]} ]} | ||||||
|  | ]. | ||||||
| 
 | 
 | ||||||
| ### Checking that the adapter is running | ### Checking that the adapter is running | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,5 +12,5 @@ | ||||||
|   ]}, |   ]}, | ||||||
|   {registered, []}, |   {registered, []}, | ||||||
|   {mod, {rabbit_stomp, []}}, |   {mod, {rabbit_stomp, []}}, | ||||||
|   {env, [{listeners, [{"127.0.0.1", 61613}]}]}, |   {env, [{tcp_listeners, [61613]}]}, | ||||||
|   {applications, [kernel, stdlib, rabbit]}]}. |   {applications, [kernel, stdlib, rabbit]}]}. | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ stop(_State) -> | ||||||
|     ok. |     ok. | ||||||
| 
 | 
 | ||||||
| parse_listener_configuration() -> | parse_listener_configuration() -> | ||||||
|     case application:get_env(listeners) of |     case application:get_env(tcp_listeners) of | ||||||
|         undefined -> throw({error, {stomp_configuration_not_found}}); |         undefined -> throw({error, {stomp_configuration_not_found}}); | ||||||
|         {ok, Listeners} -> Listeners |         {ok, Listeners} -> Listeners | ||||||
|     end. |     end. | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ | ||||||
|                 connection, subscriptions, version, |                 connection, subscriptions, version, | ||||||
|                 start_heartbeat_fun}). |                 start_heartbeat_fun}). | ||||||
| 
 | 
 | ||||||
| -record(subscription, {dest_hdr, channel, multi_ack}). | -record(subscription, {dest_hdr, channel, multi_ack, description}). | ||||||
| 
 | 
 | ||||||
| -define(SUPPORTED_VERSIONS, ["1.0", "1.1"]). | -define(SUPPORTED_VERSIONS, ["1.0", "1.1"]). | ||||||
| -define(DEFAULT_QUEUE_PREFETCH, 1). | -define(DEFAULT_QUEUE_PREFETCH, 1). | ||||||
|  | @ -124,6 +124,8 @@ handle_cast(client_timeout, State) -> | ||||||
| 
 | 
 | ||||||
| handle_info(#'basic.consume_ok'{}, State) -> | handle_info(#'basic.consume_ok'{}, State) -> | ||||||
|     {noreply, State}; |     {noreply, State}; | ||||||
|  | handle_info(#'basic.cancel_ok'{}, State) -> | ||||||
|  |     {noreply, State}; | ||||||
| handle_info({Delivery = #'basic.deliver'{}, | handle_info({Delivery = #'basic.deliver'{}, | ||||||
|              #amqp_msg{props = Props, payload = Payload}}, State) -> |              #amqp_msg{props = Props, payload = Payload}}, State) -> | ||||||
|     {noreply, send_delivery(Delivery, Props, Payload, State)}. |     {noreply, send_delivery(Delivery, Props, Payload, State)}. | ||||||
|  | @ -234,20 +236,42 @@ cancel_subscription({error, _}, State) -> | ||||||
|           "UNSUBSCRIBE must include a 'destination' or 'id' header\n", |           "UNSUBSCRIBE must include a 'destination' or 'id' header\n", | ||||||
|           State); |           State); | ||||||
| 
 | 
 | ||||||
| cancel_subscription({ok, ConsumerTag}, State = #state{subscriptions = Subs}) -> | cancel_subscription({ok, ConsumerTag, Description}, | ||||||
|  |                     State = #state{channel       = MainChannel, | ||||||
|  |                                    subscriptions = Subs}) -> | ||||||
|     case dict:find(ConsumerTag, Subs) of |     case dict:find(ConsumerTag, Subs) of | ||||||
|         error -> |         error -> | ||||||
|             error("No subscription found", |             error("No subscription found", | ||||||
|                   "UNSUBSCRIBE must refer to an existing subscription\n", |                   "UNSUBSCRIBE must refer to an existing subscription.\n" | ||||||
|  |                   "Subscription to ~p not found.\n", | ||||||
|  |                   [Description], | ||||||
|                   State); |                   State); | ||||||
|         {ok, #subscription{channel = Channel}} -> |         {ok, #subscription{channel = SubChannel}} -> | ||||||
|             ok(send_method(#'basic.cancel'{consumer_tag = ConsumerTag, |             case amqp_channel:call(SubChannel, | ||||||
|                                            nowait       = true}, |                                    #'basic.cancel'{ | ||||||
|                            Channel, |                                      consumer_tag = ConsumerTag}) of | ||||||
|                            State#state{subscriptions = |                 #'basic.cancel_ok'{consumer_tag = ConsumerTag} -> | ||||||
|                                            dict:erase(ConsumerTag, Subs)})) |                     NewSubs = dict:erase(ConsumerTag, Subs), | ||||||
|  |                     ensure_subchannel_closed(SubChannel, | ||||||
|  |                                              MainChannel, | ||||||
|  |                                              State#state{ | ||||||
|  |                                                subscriptions = NewSubs}); | ||||||
|  |                 _ -> | ||||||
|  |                     error("Failed to cancel subscription", | ||||||
|  |                           "UNSUBSCRIBE to ~p failed.\n", | ||||||
|  |                           [Description], | ||||||
|  |                           State) | ||||||
|  |             end | ||||||
|     end. |     end. | ||||||
| 
 | 
 | ||||||
|  | ensure_subchannel_closed(SubChannel, MainChannel, State) | ||||||
|  |   when SubChannel == MainChannel -> | ||||||
|  |     ok(State); | ||||||
|  | 
 | ||||||
|  | ensure_subchannel_closed(SubChannel, _MainChannel, State) -> | ||||||
|  |     amqp_channel:close(SubChannel), | ||||||
|  |     ok(State). | ||||||
|  | 
 | ||||||
| with_destination(Command, Frame, State, Fun) -> | with_destination(Command, Frame, State, Fun) -> | ||||||
|     case rabbit_stomp_frame:header(Frame, "destination") of |     case rabbit_stomp_frame:header(Frame, "destination") of | ||||||
|         {ok, DestHdr} -> |         {ok, DestHdr} -> | ||||||
|  | @ -320,7 +344,7 @@ do_subscribe(Destination, DestHdr, Frame, | ||||||
| 
 | 
 | ||||||
|     {ok, Queue} = ensure_queue(subscribe, Destination, Channel), |     {ok, Queue} = ensure_queue(subscribe, Destination, Channel), | ||||||
| 
 | 
 | ||||||
|     {ok, ConsumerTag} = rabbit_stomp_util:consumer_tag(Frame), |     {ok, ConsumerTag, Description} = rabbit_stomp_util:consumer_tag(Frame), | ||||||
| 
 | 
 | ||||||
|     amqp_channel:subscribe(Channel, |     amqp_channel:subscribe(Channel, | ||||||
|                            #'basic.consume'{ |                            #'basic.consume'{ | ||||||
|  | @ -336,9 +360,10 @@ do_subscribe(Destination, DestHdr, Frame, | ||||||
| 
 | 
 | ||||||
|     ok(State#state{subscriptions = |     ok(State#state{subscriptions = | ||||||
|                        dict:store(ConsumerTag, |                        dict:store(ConsumerTag, | ||||||
|                                   #subscription{dest_hdr  = DestHdr, |                                   #subscription{dest_hdr    = DestHdr, | ||||||
|                                                 channel   = Channel, |                                                 channel     = Channel, | ||||||
|                                                 multi_ack = IsMulti}, |                                                 multi_ack   = IsMulti, | ||||||
|  |                                                 description = Description}, | ||||||
|                                   Subs)}). |                                   Subs)}). | ||||||
| 
 | 
 | ||||||
| do_send(Destination, _DestHdr, | do_send(Destination, _DestHdr, | ||||||
|  | @ -400,7 +425,7 @@ send_delivery(Delivery = #'basic.deliver'{consumer_tag = ConsumerTag}, | ||||||
|               State); |               State); | ||||||
|         error -> |         error -> | ||||||
|             send_error("Subscription not found", |             send_error("Subscription not found", | ||||||
|                        "There is no current subscription '~s'.", |                        "There is no current subscription with tag '~s'.", | ||||||
|                        [ConsumerTag], |                        [ConsumerTag], | ||||||
|                        State) |                        State) | ||||||
|     end. |     end. | ||||||
|  | @ -414,6 +439,9 @@ send_method(Method, State = #state{channel = Channel}) -> | ||||||
| 
 | 
 | ||||||
| send_method(Method, Properties, BodyFragments, | send_method(Method, Properties, BodyFragments, | ||||||
|             State = #state{channel = Channel}) -> |             State = #state{channel = Channel}) -> | ||||||
|  |     send_method(Method, Channel, Properties, BodyFragments, State). | ||||||
|  | 
 | ||||||
|  | send_method(Method, Channel, Properties, BodyFragments, State) -> | ||||||
|     amqp_channel:call(Channel, Method, #amqp_msg{ |     amqp_channel:call(Channel, Method, #amqp_msg{ | ||||||
|                                 props = Properties, |                                 props = Properties, | ||||||
|                                 payload = lists:reverse(BodyFragments)}), |                                 payload = lists:reverse(BodyFragments)}), | ||||||
|  | @ -508,8 +536,7 @@ abort_transaction(Transaction, State0) -> | ||||||
| perform_transaction_action({Method}, State) -> | perform_transaction_action({Method}, State) -> | ||||||
|     send_method(Method, State); |     send_method(Method, State); | ||||||
| perform_transaction_action({Channel, Method}, State) -> | perform_transaction_action({Channel, Method}, State) -> | ||||||
|     amqp_channel:call(Channel, Method), |     send_method(Method, Channel, State); | ||||||
|     State; |  | ||||||
| perform_transaction_action({Method, Props, BodyFragments}, State) -> | perform_transaction_action({Method, Props, BodyFragments}, State) -> | ||||||
|     send_method(Method, Props, BodyFragments, State). |     send_method(Method, Props, BodyFragments, State). | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,25 +52,24 @@ init([Listeners]) -> | ||||||
|     {ok, {{one_for_all, 10, 10}, ChildSpecs}}. |     {ok, {{one_for_all, 10, 10}, ChildSpecs}}. | ||||||
| 
 | 
 | ||||||
| make_listener_specs(Listeners) -> | make_listener_specs(Listeners) -> | ||||||
|     lists:foldl( |     [make_listener_spec(Spec) | ||||||
|       fun({Host, Port}, Acc) -> |      || Spec <- lists:append([rabbit_networking:check_tcp_listener_address( | ||||||
|               {IPAddress, Name} = rabbit_networking:check_tcp_listener_address( |                                 rabbit_stomp_listener_sup, Listener) | ||||||
|                                     rabbit_stomp_listener_sup, |                               || Listener <- Listeners])]. | ||||||
|                                     Host, |  | ||||||
|                                     Port), |  | ||||||
|               [{Name, |  | ||||||
|                 {tcp_listener_sup, start_link, |  | ||||||
|                  [IPAddress, Port, |  | ||||||
|                   [binary, |  | ||||||
|                    {packet, raw}, |  | ||||||
|                    {reuseaddr, true}, |  | ||||||
|                    {backlog, 128}], |  | ||||||
|                   {?MODULE, listener_started, []}, |  | ||||||
|                   {?MODULE, listener_stopped, []}, |  | ||||||
|                   {?MODULE, start_client, []}, "STOMP Listener"]}, |  | ||||||
|                 transient, infinity, supervisor, [tcp_listener_sup]} | Acc] |  | ||||||
| 
 | 
 | ||||||
|       end, [], Listeners). | make_listener_spec({IPAddress, Port, Family, Name}) -> | ||||||
|  |     {Name, | ||||||
|  |      {tcp_listener_sup, start_link, | ||||||
|  |       [IPAddress, Port, | ||||||
|  |        [Family, | ||||||
|  |         binary, | ||||||
|  |         {packet, raw}, | ||||||
|  |         {reuseaddr, true}, | ||||||
|  |         {backlog, 128}], | ||||||
|  |        {?MODULE, listener_started, []}, | ||||||
|  |        {?MODULE, listener_stopped, []}, | ||||||
|  |        {?MODULE, start_client, []}, "STOMP Listener"]}, | ||||||
|  |      transient, infinity, supervisor, [tcp_listener_sup]}. | ||||||
| 
 | 
 | ||||||
| listener_started(IPAddress, Port) -> | listener_started(IPAddress, Port) -> | ||||||
|     rabbit_networking:tcp_listener_started(stomp, IPAddress, Port). |     rabbit_networking:tcp_listener_started(stomp, IPAddress, Port). | ||||||
|  |  | ||||||
|  | @ -60,11 +60,11 @@ | ||||||
| consumer_tag(Frame) -> | consumer_tag(Frame) -> | ||||||
|     case rabbit_stomp_frame:header(Frame, "id") of |     case rabbit_stomp_frame:header(Frame, "id") of | ||||||
|         {ok, Str} -> |         {ok, Str} -> | ||||||
|             {ok, list_to_binary("T_" ++ Str)}; |             {ok, list_to_binary("T_" ++ Str), "id='" ++ Str ++ "'"}; | ||||||
|         not_found -> |         not_found -> | ||||||
|             case rabbit_stomp_frame:header(Frame, "destination") of |             case rabbit_stomp_frame:header(Frame, "destination") of | ||||||
|                 {ok, DestHdr} -> |                 {ok, DestHdr} -> | ||||||
|                     {ok, list_to_binary("Q_" ++ DestHdr)}; |                     {ok, list_to_binary("Q_" ++ DestHdr), "destination='" ++ DestHdr ++ "'"}; | ||||||
|                 not_found -> |                 not_found -> | ||||||
|                     {error, missing_destination_header} |                     {error, missing_destination_header} | ||||||
|             end |             end | ||||||
|  |  | ||||||
|  | @ -49,7 +49,7 @@ class BaseTest(unittest.TestCase): | ||||||
|         self.assertEquals("foo", msg['message']) |         self.assertEquals("foo", msg['message']) | ||||||
|         self.assertEquals(dest, msg['headers']['destination']) |         self.assertEquals(dest, msg['headers']['destination']) | ||||||
| 
 | 
 | ||||||
|    def assertListener(self, errMsg, numMsgs=0, numErrs=0, numRcts=0, timeout=3): |    def assertListener(self, errMsg, numMsgs=0, numErrs=0, numRcts=0, timeout=1): | ||||||
|         if numMsgs + numErrs + numRcts > 0: |         if numMsgs + numErrs + numRcts > 0: | ||||||
|             self.assertTrue(self.listener.await(timeout), errMsg + " (#awaiting)") |             self.assertTrue(self.listener.await(timeout), errMsg + " (#awaiting)") | ||||||
|         else: |         else: | ||||||
|  | @ -58,7 +58,7 @@ class BaseTest(unittest.TestCase): | ||||||
|         self.assertEquals(numErrs, len(self.listener.errors), errMsg + " (#errors)") |         self.assertEquals(numErrs, len(self.listener.errors), errMsg + " (#errors)") | ||||||
|         self.assertEquals(numRcts, len(self.listener.receipts), errMsg + " (#receipts)") |         self.assertEquals(numRcts, len(self.listener.receipts), errMsg + " (#receipts)") | ||||||
| 
 | 
 | ||||||
|    def assertListenerAfter(self, verb, errMsg="", numMsgs=0, numErrs=0, numRcts=0, timeout=3): |    def assertListenerAfter(self, verb, errMsg="", numMsgs=0, numErrs=0, numRcts=0, timeout=1): | ||||||
|         num = numMsgs + numErrs + numRcts |         num = numMsgs + numErrs + numRcts | ||||||
|         self.listener.reset(num if num>0 else 1) |         self.listener.reset(num if num>0 else 1) | ||||||
|         verb() |         verb() | ||||||
|  | @ -77,13 +77,13 @@ class WaitableListener(object): | ||||||
| 
 | 
 | ||||||
|     def on_receipt(self, headers, message): |     def on_receipt(self, headers, message): | ||||||
|         if self.debug: |         if self.debug: | ||||||
|             print '(on_message) message:', message, 'headers:', headers |             print '(on_receipt) message:', message, 'headers:', headers | ||||||
|         self.receipts.append({'message' : message, 'headers' : headers}) |         self.receipts.append({'message' : message, 'headers' : headers}) | ||||||
|         self.latch.countdown() |         self.latch.countdown() | ||||||
| 
 | 
 | ||||||
|     def on_error(self, headers, message): |     def on_error(self, headers, message): | ||||||
|         if self.debug: |         if self.debug: | ||||||
|             print '(on_message) message:', message, 'headers:', headers |             print '(on_error) message:', message, 'headers:', headers | ||||||
|         self.errors.append({'message' : message, 'headers' : headers}) |         self.errors.append({'message' : message, 'headers' : headers}) | ||||||
|         self.latch.countdown() |         self.latch.countdown() | ||||||
| 
 | 
 | ||||||
|  | @ -93,11 +93,12 @@ class WaitableListener(object): | ||||||
|         self.messages.append({'message' : message, 'headers' : headers}) |         self.messages.append({'message' : message, 'headers' : headers}) | ||||||
|         self.latch.countdown() |         self.latch.countdown() | ||||||
| 
 | 
 | ||||||
|     def reset(self,count=1): |     def reset(self, count=1): | ||||||
|         if self.debug: |         if self.debug: | ||||||
|             print '(reset listener) #messages:', len(self.messages), |             print '(reset listener)', | ||||||
|             print '#errors', len(self.errors), |             print '#messages:', len(self.messages), | ||||||
|             print '#receipts', len(self.receipts), 'Now expecting:', count |             print '#errors:', len(self.errors), | ||||||
|  |             print '#receipts:', len(self.receipts), 'Now expecting:', count | ||||||
|         self.messages = [] |         self.messages = [] | ||||||
|         self.errors = [] |         self.errors = [] | ||||||
|         self.receipts = [] |         self.receipts = [] | ||||||
|  | @ -116,7 +117,8 @@ class Latch(object): | ||||||
| 
 | 
 | ||||||
|    def countdown(self): |    def countdown(self): | ||||||
|       self.cond.acquire() |       self.cond.acquire() | ||||||
|       self.count -= 1 |       if self.count > 0: | ||||||
|  |          self.count -= 1 | ||||||
|       if self.count == 0: |       if self.count == 0: | ||||||
|          self.cond.notify_all() |          self.cond.notify_all() | ||||||
|       self.cond.release() |       self.cond.release() | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import unittest | import unittest | ||||||
| import stomp | import stomp | ||||||
| import base | import base | ||||||
|  | import time | ||||||
| 
 | 
 | ||||||
| class TestExchange(base.BaseTest): | class TestExchange(base.BaseTest): | ||||||
| 
 | 
 | ||||||
|  | @ -32,7 +33,7 @@ class TestExchange(base.BaseTest): | ||||||
|         self.assertEquals("not_found", err['headers']['message']) |         self.assertEquals("not_found", err['headers']['message']) | ||||||
|         self.assertEquals("no exchange 'does.not.exist' in vhost '/'\n", |         self.assertEquals("no exchange 'does.not.exist' in vhost '/'\n", | ||||||
|                           err['message']) |                           err['message']) | ||||||
| 
 |         time.sleep(1) | ||||||
|         self.assertFalse(self.conn.is_connected()) |         self.assertFalse(self.conn.is_connected()) | ||||||
| 
 | 
 | ||||||
|     def __test_exchange_send_rec(self, exchange, route = None): |     def __test_exchange_send_rec(self, exchange, route = None): | ||||||
|  |  | ||||||
|  | @ -65,4 +65,3 @@ class TestErrors(base.BaseTest): | ||||||
|                               dtype + " destination\n", |                               dtype + " destination\n", | ||||||
|                           err['message']) |                           err['message']) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -7,21 +7,46 @@ class TestLifecycle(base.BaseTest): | ||||||
| 
 | 
 | ||||||
|     def test_unsubscribe_exchange_destination(self): |     def test_unsubscribe_exchange_destination(self): | ||||||
|         ''' Test UNSUBSCRIBE command with exchange''' |         ''' Test UNSUBSCRIBE command with exchange''' | ||||||
|         self.unsub_test(self.sub_and_send("/exchange/amq.fanout")) |         d = "/exchange/amq.fanout" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d)) | ||||||
|  | 
 | ||||||
|  |     def test_unsubscribe_exchange_destination_with_receipt(self): | ||||||
|  |         ''' Test receipted UNSUBSCRIBE command with exchange''' | ||||||
|  |         d = "/exchange/amq.fanout" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d, receipt="unsub.rct"), numRcts=1) | ||||||
| 
 | 
 | ||||||
|     def test_unsubscribe_queue_destination(self): |     def test_unsubscribe_queue_destination(self): | ||||||
|         ''' Test UNSUBSCRIBE command with queue''' |         ''' Test UNSUBSCRIBE command with queue''' | ||||||
|         self.unsub_test(self.sub_and_send("/queue/unsub01")) |         d = "/queue/unsub01" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d)) | ||||||
|  | 
 | ||||||
|  |     def test_unsubscribe_queue_destination_with_receipt(self): | ||||||
|  |         ''' Test receipted UNSUBSCRIBE command with queue''' | ||||||
|  |         d = "/queue/unsub02" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d, receipt="unsub.rct"), numRcts=1) | ||||||
| 
 | 
 | ||||||
|     def test_unsubscribe_exchange_id(self): |     def test_unsubscribe_exchange_id(self): | ||||||
|         ''' Test UNSUBSCRIBE command with exchange by id''' |         ''' Test UNSUBSCRIBE command with exchange by id''' | ||||||
|         self.unsub_test(self.subid_and_send("/exchange/amq.fanout", "exchid")) |         d = "/exchange/amq.fanout" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d, subid="exchid")) | ||||||
|  | 
 | ||||||
|  |     def test_unsubscribe_exchange_id_with_receipt(self): | ||||||
|  |         ''' Test receipted UNSUBSCRIBE command with exchange by id''' | ||||||
|  |         d = "/exchange/amq.fanout" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d, subid="exchid", receipt="unsub.rct"), numRcts=1) | ||||||
| 
 | 
 | ||||||
|     def test_unsubscribe_queue_id(self): |     def test_unsubscribe_queue_id(self): | ||||||
|         ''' Test UNSUBSCRIBE command with queue by id''' |         ''' Test UNSUBSCRIBE command with queue by id''' | ||||||
|         self.unsub_test(self.subid_and_send("/queue/unsub02", "queid")) |         d = "/queue/unsub03" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d, subid="queid")) | ||||||
|  | 
 | ||||||
|  |     def test_unsubscribe_queue_id_with_receipt(self): | ||||||
|  |         ''' Test receipted UNSUBSCRIBE command with queue by id''' | ||||||
|  |         d = "/queue/unsub04" | ||||||
|  |         self.unsub_test(d, self.sub_and_send(d, subid="queid", receipt="unsub.rct"), numRcts=1) | ||||||
| 
 | 
 | ||||||
|     def test_connect_version_1_1(self): |     def test_connect_version_1_1(self): | ||||||
|  |         ''' Test CONNECT with version 1.1''' | ||||||
|         self.conn.disconnect() |         self.conn.disconnect() | ||||||
|         new_conn = self.create_connection(version="1.1,1.0") |         new_conn = self.create_connection(version="1.1,1.0") | ||||||
|         try: |         try: | ||||||
|  | @ -30,6 +55,7 @@ class TestLifecycle(base.BaseTest): | ||||||
|             new_conn.disconnect() |             new_conn.disconnect() | ||||||
| 
 | 
 | ||||||
|     def test_heartbeat_disconnects_client(self): |     def test_heartbeat_disconnects_client(self): | ||||||
|  |         ''' Test heartbeat disconnection''' | ||||||
|         self.conn.disconnect() |         self.conn.disconnect() | ||||||
|         new_conn = self.create_connection(heartbeat="1500,0") |         new_conn = self.create_connection(heartbeat="1500,0") | ||||||
|         try: |         try: | ||||||
|  | @ -42,9 +68,8 @@ class TestLifecycle(base.BaseTest): | ||||||
|             if new_conn.is_connected(): |             if new_conn.is_connected(): | ||||||
|                 new_conn.disconnect() |                 new_conn.disconnect() | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     def test_unsupported_version(self): |     def test_unsupported_version(self): | ||||||
|  |         ''' Test unsupported version on CONNECT command''' | ||||||
|         self.conn.disconnect() |         self.conn.disconnect() | ||||||
|         new_conn = stomp.Connection(user="guest", |         new_conn = stomp.Connection(user="guest", | ||||||
|                                     passcode="guest", |                                     passcode="guest", | ||||||
|  | @ -62,29 +87,35 @@ class TestLifecycle(base.BaseTest): | ||||||
|                 new_conn.disconnect() |                 new_conn.disconnect() | ||||||
| 
 | 
 | ||||||
|     def test_disconnect(self): |     def test_disconnect(self): | ||||||
|         ''' Run DISCONNECT command ''' |         ''' Test DISCONNECT command''' | ||||||
|         self.conn.disconnect() |         self.conn.disconnect() | ||||||
|         self.assertFalse(self.conn.is_connected()) |         self.assertFalse(self.conn.is_connected()) | ||||||
| 
 | 
 | ||||||
|     def unsub_test(self, verbs): |     def unsub_test(self, dest, verbs, numRcts=0): | ||||||
|  |         def afterfun(): | ||||||
|  |             self.conn.send("after-test", destination=dest) | ||||||
|         subverb, unsubverb = verbs |         subverb, unsubverb = verbs | ||||||
|         self.assertListenerAfter(subverb, |         self.assertListenerAfter(subverb, numMsgs=1, | ||||||
|                            numMsgs=1, errMsg="FAILED to subscribe and send") |                            errMsg="FAILED to subscribe and send") | ||||||
|         self.assertListenerAfter(unsubverb, |         self.assertListenerAfter(unsubverb, numRcts=numRcts,  | ||||||
|  |                            errMsg="Incorrect responses from UNSUBSCRIBE") | ||||||
|  |         self.assertListenerAfter(afterfun, | ||||||
|                            errMsg="Still receiving messages") |                            errMsg="Still receiving messages") | ||||||
| 
 | 
 | ||||||
|     def subid_and_send(self, dest, subid): |     def sub_and_send(self, dest, subid="", receipt=""): | ||||||
|         def subfun(): |         def subfun(): | ||||||
|             self.conn.subscribe(destination=dest, id=subid) |             if subid=="": | ||||||
|  |                 self.conn.subscribe(destination=dest) | ||||||
|  |             else: | ||||||
|  |                 self.conn.subscribe(destination=dest, id=subid) | ||||||
|             self.conn.send("test", destination=dest) |             self.conn.send("test", destination=dest) | ||||||
|         def unsubfun(): |         def unsubfun(): | ||||||
|             self.conn.unsubscribe(id=subid) |             if subid=="" and receipt=="": | ||||||
|         return subfun, unsubfun |                 self.conn.unsubscribe(destination=dest) | ||||||
| 
 |             elif receipt=="": | ||||||
|     def sub_and_send(self, dest): |                 self.conn.unsubscribe(id=subid) | ||||||
|         def subfun(): |             elif subid=="": | ||||||
|             self.conn.subscribe(destination=dest) |                 self.conn.unsubscribe(destination=dest, receipt=receipt) | ||||||
|             self.conn.send("test", destination=dest) |             else: | ||||||
|         def unsubfun(): |                 self.conn.unsubscribe(id=subid, receipt=receipt) | ||||||
|             self.conn.unsubscribe(destination=dest) |  | ||||||
|         return subfun, unsubfun |         return subfun, unsubfun | ||||||
|  |  | ||||||
|  | @ -150,11 +150,11 @@ ack_mode_client_individual_test() -> | ||||||
| 
 | 
 | ||||||
| consumer_tag_id_test() -> | consumer_tag_id_test() -> | ||||||
|     Frame = #stomp_frame{headers = [{"id", "foo"}]}, |     Frame = #stomp_frame{headers = [{"id", "foo"}]}, | ||||||
|     {ok, <<"T_foo">>} = rabbit_stomp_util:consumer_tag(Frame). |     {ok, <<"T_foo">>, _} = rabbit_stomp_util:consumer_tag(Frame). | ||||||
| 
 | 
 | ||||||
| consumer_tag_destination_test() -> | consumer_tag_destination_test() -> | ||||||
|     Frame = #stomp_frame{headers = [{"destination", "foo"}]}, |     Frame = #stomp_frame{headers = [{"destination", "foo"}]}, | ||||||
|     {ok, <<"Q_foo">>} = rabbit_stomp_util:consumer_tag(Frame). |     {ok, <<"Q_foo">>, _} = rabbit_stomp_util:consumer_tag(Frame). | ||||||
| 
 | 
 | ||||||
| consumer_tag_invalid_test() -> | consumer_tag_invalid_test() -> | ||||||
|     Frame = #stomp_frame{headers = []}, |     Frame = #stomp_frame{headers = []}, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue