Merge branch 'stable'
This commit is contained in:
		
						commit
						5b8ba91bbb
					
				|  | @ -14,3 +14,5 @@ erl_crash.dump | |||
| /tmp/ | ||||
| /deps/stomppy/stomppy/ | ||||
| /deps/stomppy/stomppy-git/ | ||||
| /deps/pika/pika/ | ||||
| /deps/pika/pika-git/ | ||||
|  |  | |||
|  | @ -0,0 +1,27 @@ | |||
| UPSTREAM_GIT=https://github.com/pika/pika.git | ||||
| REVISION=0.9.14 | ||||
| 
 | ||||
| LIB_DIR=pika | ||||
| CHECKOUT_DIR=pika-git | ||||
| 
 | ||||
| TARGETS=$(LIB_DIR) | ||||
| 
 | ||||
| all: $(TARGETS) | ||||
| 
 | ||||
| clean: | ||||
| 	rm -rf $(LIB_DIR) | ||||
| 
 | ||||
| distclean: clean | ||||
| 	rm -rf $(CHECKOUT_DIR) | ||||
| 
 | ||||
| $(LIB_DIR) : $(CHECKOUT_DIR) | ||||
| 	rm -rf $@ | ||||
| 	cp -R $< $@ | ||||
| 
 | ||||
| $(CHECKOUT_DIR): | ||||
| 	git clone $(UPSTREAM_GIT) $@ | ||||
| 	(cd $@ && git checkout $(REVISION)) || rm -rf $@ | ||||
| 
 | ||||
| echo-revision: | ||||
| 	@echo $(REVISION) | ||||
| 
 | ||||
|  | @ -43,9 +43,26 @@ | |||
| -define(HEADER_TYPE, "type"). | ||||
| -define(HEADER_USER_ID, "user-id"). | ||||
| -define(HEADER_VERSION, "version"). | ||||
| -define(HEADER_X_DEAD_LETTER_EXCHANGE, "x-dead-letter-exchange"). | ||||
| -define(HEADER_X_DEAD_LETTER_ROUTING_KEY, "x-dead-letter-routing-key"). | ||||
| -define(HEADER_X_EXPIRES, "x-expires"). | ||||
| -define(HEADER_X_MAX_LENGTH, "x-max-length"). | ||||
| -define(HEADER_X_MAX_LENGTH_BYTES, "x-max-length-bytes"). | ||||
| -define(HEADER_X_MAX_PRIORITY, "x-max-priority"). | ||||
| -define(HEADER_X_MESSAGE_TTL, "x-message-ttl"). | ||||
| 
 | ||||
| -define(MESSAGE_ID_SEPARATOR, "@@"). | ||||
| 
 | ||||
| -define(HEADERS_NOT_ON_SEND, [?HEADER_MESSAGE_ID]). | ||||
| 
 | ||||
| -define(TEMP_QUEUE_ID_PREFIX, "/temp-queue/"). | ||||
| 
 | ||||
| -define(HEADER_ARGUMENTS, [ | ||||
|                            ?HEADER_X_DEAD_LETTER_EXCHANGE, | ||||
|                            ?HEADER_X_DEAD_LETTER_ROUTING_KEY, | ||||
|                            ?HEADER_X_EXPIRES, | ||||
|                            ?HEADER_X_MAX_LENGTH, | ||||
|                            ?HEADER_X_MAX_LENGTH_BYTES, | ||||
|                            ?HEADER_X_MAX_PRIORITY, | ||||
|                            ?HEADER_X_MESSAGE_TTL | ||||
|                           ]). | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| RELEASABLE:=true | ||||
| DEPS:=rabbitmq-server rabbitmq-erlang-client rabbitmq-test | ||||
| #STANDALONE_TEST_COMMANDS:=eunit:test([rabbit_stomp_test_util,rabbit_stomp_test_frame],[verbose])
 | ||||
| STANDALONE_TEST_COMMANDS:=eunit:test([rabbit_stomp_test_util,rabbit_stomp_test_frame],[verbose]) | ||||
| WITH_BROKER_TEST_SCRIPTS:=$(PACKAGE_DIR)/test/src/test.py $(PACKAGE_DIR)/test/src/test_connect_options.py $(PACKAGE_DIR)/test/src/test_ssl.py | ||||
| #WITH_BROKER_TEST_COMMANDS:=rabbit_stomp_test:all_tests() rabbit_stomp_amqqueue_test:all_tests()
 | ||||
| WITH_BROKER_TEST_COMMANDS:=rabbit_stomp_test:all_tests() rabbit_stomp_amqqueue_test:all_tests() | ||||
| WITH_BROKER_TEST_CONFIG:=$(PACKAGE_DIR)/test/ebin/test | ||||
| 
 | ||||
| define package_rules | ||||
|  | @ -14,11 +14,13 @@ $(PACKAGE_DIR)+pre-test:: | |||
| 	sed -e "s|%%CERTS_DIR%%|$(abspath $(PACKAGE_DIR))/test/certs|g" < $(PACKAGE_DIR)/test/src/test.config > $(PACKAGE_DIR)/test/ebin/test.config | ||||
| 	$(MAKE) -C $(PACKAGE_DIR)/../rabbitmq-test/certs all PASSWORD=test DIR=$(abspath $(PACKAGE_DIR))/test/certs | ||||
| 	$(MAKE) -C $(PACKAGE_DIR)/deps/stomppy | ||||
| 	$(MAKE) -C $(PACKAGE_DIR)/deps/pika | ||||
| 
 | ||||
| $(PACKAGE_DIR)+clean:: | ||||
| 	rm -rf $(PACKAGE_DIR)/test/certs | ||||
| 
 | ||||
| $(PACKAGE_DIR)+clean-with-deps:: | ||||
| 	$(MAKE) -C $(PACKAGE_DIR)/deps/stomppy distclean | ||||
| 	$(MAKE) -C $(PACKAGE_DIR)/deps/pika distclean | ||||
| 
 | ||||
| endef | ||||
|  |  | |||
|  | @ -973,7 +973,7 @@ millis_to_seconds(M)               -> M div 1000. | |||
| ensure_endpoint(_Direction, {queue, []}, _Frame, _Channel, _State) -> | ||||
|     {error, {invalid_destination, "Destination cannot be blank"}}; | ||||
| 
 | ||||
| ensure_endpoint(source, EndPoint, Frame, Channel, State) -> | ||||
| ensure_endpoint(source, EndPoint, {_, _, Headers, _} = Frame, Channel, State) -> | ||||
|     Params = | ||||
|         case rabbit_stomp_frame:boolean_header( | ||||
|                Frame, ?HEADER_PERSISTENT, false) of | ||||
|  | @ -998,10 +998,12 @@ ensure_endpoint(source, EndPoint, Frame, Channel, State) -> | |||
|                   end}, | ||||
|                  {durable, false}] | ||||
|         end, | ||||
|     rabbit_routing_util:ensure_endpoint(source, Channel, EndPoint, Params, State); | ||||
|     Arguments = rabbit_stomp_util:build_arguments(Headers), | ||||
|     rabbit_routing_util:ensure_endpoint(source, Channel, EndPoint, [Arguments | Params], State); | ||||
| 
 | ||||
| ensure_endpoint(Direction, Endpoint, _Frame, Channel, State) -> | ||||
|     rabbit_routing_util:ensure_endpoint(Direction, Channel, Endpoint, State). | ||||
| ensure_endpoint(Direction, Endpoint, {_, _, Headers, _}, Channel, State) -> | ||||
|     Arguments = rabbit_stomp_util:build_arguments(Headers), | ||||
|     rabbit_routing_util:ensure_endpoint(Direction, Channel, Endpoint, [Arguments], State). | ||||
| 
 | ||||
| %%---------------------------------------------------------------------------- | ||||
| %% Success/error handling | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ | |||
| -export([longstr_field/2]). | ||||
| -export([ack_mode/1, consumer_tag_reply_to/1, consumer_tag/1, message_headers/1, | ||||
|          headers_post_process/1, headers/5, message_properties/1, tag_to_id/1, | ||||
|          msg_header_name/1, ack_header_name/1]). | ||||
|          msg_header_name/1, ack_header_name/1, build_arguments/1]). | ||||
| -export([negotiate_version/2]). | ||||
| -export([trim_headers/1]). | ||||
| 
 | ||||
|  | @ -260,6 +260,41 @@ msg_header_name("1.2") -> ?HEADER_ACK; | |||
| msg_header_name("1.1") -> ?HEADER_MESSAGE_ID; | ||||
| msg_header_name("1.0") -> ?HEADER_MESSAGE_ID. | ||||
| 
 | ||||
| build_arguments(Headers) -> | ||||
|     Arguments = | ||||
|         lists:foldl(fun({K, V}, Acc) -> | ||||
|                             case lists:member(K, ?HEADER_ARGUMENTS) of | ||||
|                                 true  -> [build_argument(K, V) | Acc]; | ||||
|                                 false -> Acc | ||||
|                             end | ||||
|                     end, | ||||
|                     [], | ||||
|                     Headers), | ||||
|     {arguments, Arguments}. | ||||
| 
 | ||||
| %% build the actual value thru pattern matching | ||||
| build_argument(?HEADER_X_DEAD_LETTER_EXCHANGE, Val) -> | ||||
|     {list_to_binary(?HEADER_X_DEAD_LETTER_EXCHANGE), longstr, | ||||
|      list_to_binary(string:strip(Val))}; | ||||
| build_argument(?HEADER_X_DEAD_LETTER_ROUTING_KEY, Val) -> | ||||
|     {list_to_binary(?HEADER_X_DEAD_LETTER_ROUTING_KEY), longstr, | ||||
|      list_to_binary(string:strip(Val))}; | ||||
| build_argument(?HEADER_X_EXPIRES, Val) -> | ||||
|     {list_to_binary(?HEADER_X_EXPIRES), long, | ||||
|      list_to_integer(string:strip(Val))}; | ||||
| build_argument(?HEADER_X_MAX_LENGTH, Val) -> | ||||
|     {list_to_binary(?HEADER_X_MAX_LENGTH), long, | ||||
|      list_to_integer(string:strip(Val))}; | ||||
| build_argument(?HEADER_X_MAX_LENGTH_BYTES, Val) -> | ||||
|     {list_to_binary(?HEADER_X_MAX_LENGTH_BYTES), long, | ||||
|      list_to_integer(string:strip(Val))}; | ||||
| build_argument(?HEADER_X_MAX_PRIORITY, Val) -> | ||||
|     {list_to_binary(?HEADER_X_MAX_PRIORITY), long, | ||||
|      list_to_integer(string:strip(Val))}; | ||||
| build_argument(?HEADER_X_MESSAGE_TTL, Val) -> | ||||
|     {list_to_binary(?HEADER_X_MESSAGE_TTL), long, | ||||
|      list_to_integer(string:strip(Val))}. | ||||
| 
 | ||||
| %%-------------------------------------------------------------------- | ||||
| %% Destination Formatting | ||||
| %%-------------------------------------------------------------------- | ||||
|  |  | |||
|  | @ -499,8 +499,9 @@ class TestDurableSubscription(base.BaseTest): | |||
|             self.__subscribe(destination, conn2, "other.id") | ||||
| 
 | ||||
|             for l in [self.listener, listener2]: | ||||
|                 self.assertTrue(l.await(20)) | ||||
|                 self.assertEquals(100, len(l.messages)) | ||||
|                 self.assertTrue(l.await(15)) | ||||
|                 self.assertTrue(len(l.messages) >= 90) | ||||
|                 self.assertTrue(len(l.messages) <= 100) | ||||
| 
 | ||||
|         finally: | ||||
|             conn2.disconnect() | ||||
|  |  | |||
|  | @ -0,0 +1,79 @@ | |||
| import unittest | ||||
| import stomp | ||||
| import pika | ||||
| import base | ||||
| import time | ||||
| 
 | ||||
| class TestQueueProperties(base.BaseTest): | ||||
| 
 | ||||
|     def test_subscribe(self): | ||||
|         destination = "/queue/queue-properties-subscribe-test" | ||||
| 
 | ||||
|         # subscribe | ||||
|         self.subscribe_dest(self.conn, destination, None, | ||||
|                             headers={ | ||||
|                                 'x-message-ttl': 60000, | ||||
|                                 'x-expires': 70000, | ||||
|                                 'x-max-length': 10, | ||||
|                                 'x-max-length-bytes': 20000, | ||||
|                                 'x-dead-letter-exchange': 'dead-letter-exchange', | ||||
|                                 'x-dead-letter-routing-key': 'dead-letter-routing-key', | ||||
|                                 'x-max-priority': 6, | ||||
|                                 }) | ||||
| 
 | ||||
|         # now try to declare the queue using pika | ||||
|         # if the properties are the same we should | ||||
|         # not get any error | ||||
|         connection = pika.BlockingConnection(pika.ConnectionParameters( | ||||
|                     host='localhost')) | ||||
|         channel = connection.channel() | ||||
|         channel.queue_declare(queue='queue-properties-subscribe-test', | ||||
|                               durable=True, | ||||
|                               arguments={ | ||||
|                                   'x-message-ttl': 60000, | ||||
|                                   'x-expires': 70000, | ||||
|                                   'x-max-length': 10, | ||||
|                                   'x-max-length-bytes': 20000, | ||||
|                                   'x-dead-letter-exchange': 'dead-letter-exchange', | ||||
|                                   'x-dead-letter-routing-key': 'dead-letter-routing-key', | ||||
|                                   'x-max-priority': 6, | ||||
|                                   }) | ||||
| 
 | ||||
|         self.conn.disconnect() | ||||
|         connection.close() | ||||
| 
 | ||||
|     def test_send(self): | ||||
|         destination = "/queue/queue-properties-send-test" | ||||
| 
 | ||||
|         # send | ||||
|         self.conn.send(destination, "test1", | ||||
|                        headers={ | ||||
|                            'x-message-ttl': 60000, | ||||
|                            'x-expires': 70000, | ||||
|                            'x-max-length': 10, | ||||
|                            'x-max-length-bytes': 20000, | ||||
|                            'x-dead-letter-exchange': 'dead-letter-exchange', | ||||
|                            'x-dead-letter-routing-key': 'dead-letter-routing-key', | ||||
|                            'x-max-priority': 6, | ||||
|                            }) | ||||
| 
 | ||||
|         # now try to declare the queue using pika | ||||
|         # if the properties are the same we should | ||||
|         # not get any error | ||||
|         connection = pika.BlockingConnection(pika.ConnectionParameters( | ||||
|                     host='localhost')) | ||||
|         channel = connection.channel() | ||||
|         channel.queue_declare(queue='queue-properties-send-test', | ||||
|                               durable=True, | ||||
|                               arguments={ | ||||
|                                   'x-message-ttl': 60000, | ||||
|                                   'x-expires': 70000, | ||||
|                                   'x-max-length': 10, | ||||
|                                   'x-max-length-bytes': 20000, | ||||
|                                   'x-dead-letter-exchange': 'dead-letter-exchange', | ||||
|                                   'x-dead-letter-routing-key': 'dead-letter-routing-key', | ||||
|                                   'x-max-priority': 6, | ||||
|                                   }) | ||||
| 
 | ||||
|         self.conn.disconnect() | ||||
|         connection.close() | ||||
|  | @ -73,6 +73,8 @@ parse(Payload, Client = {Sock, FramesRev}, FrameState, Length) -> | |||
|     case rabbit_stomp_frame:parse(Payload, FrameState) of | ||||
|         {ok, Frame, <<>>} -> | ||||
|             recv({Sock, lists:reverse([Frame | FramesRev])}); | ||||
|         {ok, Frame, <<"\n">>} -> | ||||
|             recv({Sock, lists:reverse([Frame | FramesRev])}); | ||||
|         {ok, Frame, Rest} -> | ||||
|             parse(Rest, {Sock, [Frame | FramesRev]}, | ||||
|                   rabbit_stomp_frame:initial_state(), Length); | ||||
|  |  | |||
|  | @ -40,33 +40,6 @@ parse_simple_frame_gen(Term) -> | |||
|     #stomp_frame{body_iolist = Body} = Frame, | ||||
|     ?assertEqual(<<"Body Content">>, iolist_to_binary(Body)). | ||||
| 
 | ||||
| parse_simple_frame_with_null_test() -> | ||||
|     Headers = [{"header1", "value1"}, {"header2", "value2"}, | ||||
|                {?HEADER_CONTENT_LENGTH, "12"}], | ||||
|     Content = frame_string("COMMAND", | ||||
|                            Headers, | ||||
|                            "Body\0Content"), | ||||
|     {"COMMAND", Frame, _State} = parse_complete(Content), | ||||
|     [?assertEqual({ok, Value}, | ||||
|                   rabbit_stomp_frame:header(Frame, Key)) || | ||||
|         {Key, Value} <- Headers], | ||||
|     #stomp_frame{body_iolist = Body} = Frame, | ||||
|     ?assertEqual(<<"Body\0Content">>, iolist_to_binary(Body)). | ||||
| 
 | ||||
| parse_large_content_frame_with_nulls_test() -> | ||||
|     BodyContent = string:copies("012345678\0", 1024), | ||||
|     Headers = [{"header1", "value1"}, {"header2", "value2"}, | ||||
|                {?HEADER_CONTENT_LENGTH, integer_to_list(string:len(BodyContent))}], | ||||
|     Content = frame_string("COMMAND", | ||||
|                            Headers, | ||||
|                            BodyContent), | ||||
|     {"COMMAND", Frame, _State} = parse_complete(Content), | ||||
|     [?assertEqual({ok, Value}, | ||||
|                   rabbit_stomp_frame:header(Frame, Key)) || | ||||
|         {Key, Value} <- Headers], | ||||
|     #stomp_frame{body_iolist = Body} = Frame, | ||||
|     ?assertEqual(list_to_binary(BodyContent), iolist_to_binary(Body)). | ||||
| 
 | ||||
| parse_command_only_test() -> | ||||
|     {ok, #stomp_frame{command = "COMMAND"}, _Rest} = parse("COMMAND\n\n\0"). | ||||
| 
 | ||||
|  | @ -167,7 +140,7 @@ header_value_with_colon_test() -> | |||
|                                body_iolist = []}). | ||||
| 
 | ||||
| headers_escaping_roundtrip_test() -> | ||||
|     Content = "COMMAND\nhead\\r\\c\\ner:\\c\\n\\r\\\\\n\n\0", | ||||
|     Content = "COMMAND\nhead\\r\\c\\ner:\\c\\n\\r\\\\\n\n\0\n", | ||||
|     {ok, Frame, _} = parse(Content), | ||||
|     {ok, Val} = rabbit_stomp_frame:header(Frame, "head\r:\ner"), | ||||
|     ?assertEqual(":\n\r\\", Val), | ||||
|  | @ -189,5 +162,5 @@ frame_string(Command, Headers, BodyContent) -> | |||
| frame_string(Command, Headers, BodyContent, Term) -> | ||||
|     HeaderString = | ||||
|         lists:flatten([Key ++ ":" ++ Value ++ Term || {Key, Value} <- Headers]), | ||||
|     Command ++ Term ++ HeaderString ++ Term ++ BodyContent ++ "\0". | ||||
|     Command ++ Term ++ HeaderString ++ Term ++ BodyContent ++ "\0" ++ "\n". | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ if __name__ == '__main__': | |||
|         'ack', | ||||
|         'errors', | ||||
|         'reliability', | ||||
|         'queue_properties', | ||||
|     ] | ||||
|     test_runner.run_unittests(modules) | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import os | |||
| def add_deps_to_path(): | ||||
|     deps_dir = os.path.realpath(os.path.join(__file__, "..", "..", "..", "deps")) | ||||
|     sys.path.append(os.path.join(deps_dir, "stomppy", "stomppy")) | ||||
|     sys.path.append(os.path.join(deps_dir, "pika", "pika")) | ||||
| 
 | ||||
| def run_unittests(modules): | ||||
|     add_deps_to_path() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue