@@ -108,6 +108,12 @@ groups() ->
108
108
classic_priority_queue ,
109
109
dead_letter_headers_exchange ,
110
110
dead_letter_reject ,
111
+ dead_letter_reject_message_order_classic_queue ,
112
+ dead_letter_reject_message_order_quorum_queue ,
113
+ accept_multiple_message_order_classic_queue ,
114
+ accept_multiple_message_order_quorum_queue ,
115
+ release_multiple_message_order_classic_queue ,
116
+ release_multiple_message_order_quorum_queue ,
111
117
immutable_bare_message ,
112
118
receive_many_made_available_over_time_classic_queue ,
113
119
receive_many_made_available_over_time_quorum_queue ,
@@ -158,7 +164,10 @@ groups() ->
158
164
init_per_suite (Config ) ->
159
165
{ok , _ } = application :ensure_all_started (amqp10_client ),
160
166
rabbit_ct_helpers :log_environment (),
161
- Config .
167
+ rabbit_ct_helpers :merge_app_env (
168
+ Config , {rabbit , [{quorum_tick_interval , 1000 },
169
+ {stream_tick_interval , 1000 }
170
+ ]}).
162
171
163
172
end_per_suite (Config ) ->
164
173
Config .
@@ -3747,6 +3756,97 @@ dead_letter_reject(Config) ->
3747
3756
ok = end_session_sync (Session ),
3748
3757
ok = amqp10_client :close_connection (Connection ).
3749
3758
3759
+ dead_letter_reject_message_order_classic_queue (Config ) ->
3760
+ dead_letter_reject_message_order (<<" classic" >>, Config ).
3761
+
3762
+ dead_letter_reject_message_order_quorum_queue (Config ) ->
3763
+ dead_letter_reject_message_order (<<" quorum" >>, Config ).
3764
+
3765
+ dead_letter_reject_message_order (QType , Config ) ->
3766
+ {Connection , Session , LinkPair } = init (Config ),
3767
+ QName1 = <<" q1" >>,
3768
+ QName2 = <<" q2" >>,
3769
+ {ok , #{type := QType }} = rabbitmq_amqp_client :declare_queue (
3770
+ LinkPair ,
3771
+ QName1 ,
3772
+ #{arguments => #{<<" x-queue-type" >> => {utf8 , QType },
3773
+ <<" x-dead-letter-exchange" >> => {utf8 , <<>>},
3774
+ <<" x-dead-letter-routing-key" >> => {utf8 , QName2 }
3775
+ }}),
3776
+ % % We don't care about the target dead letter queue type.
3777
+ {ok , _ } = rabbitmq_amqp_client :declare_queue (LinkPair , QName2 , #{}),
3778
+
3779
+ {ok , Sender } = amqp10_client :attach_sender_link (
3780
+ Session , <<" sender" >>, <<" /queue/" , QName1 /binary >>, unsettled ),
3781
+ wait_for_credit (Sender ),
3782
+ {ok , Receiver1 } = amqp10_client :attach_receiver_link (
3783
+ Session , <<" receiver 1" >>, <<" /queue/" , QName1 /binary >>, unsettled ),
3784
+ {ok , Receiver2 } = amqp10_client :attach_receiver_link (
3785
+ Session , <<" receiver 2" >>, <<" /queue/" , QName2 /binary >>, unsettled ),
3786
+
3787
+ [begin
3788
+ Bin = integer_to_binary (N ),
3789
+ Msg = amqp10_msg :new (Bin , Bin , true ),
3790
+ ok = amqp10_client :send_msg (Sender , Msg )
3791
+ end || N <- lists :seq (1 , 5 )],
3792
+
3793
+ {ok , Msg1 } = amqp10_client :get_msg (Receiver1 ),
3794
+ {ok , Msg2 } = amqp10_client :get_msg (Receiver1 ),
3795
+ {ok , _Msg3 } = amqp10_client :get_msg (Receiver1 ),
3796
+ {ok , Msg4 } = amqp10_client :get_msg (Receiver1 ),
3797
+ {ok , Msg5 } = amqp10_client :get_msg (Receiver1 ),
3798
+ assert_messages (QName1 , 5 , 5 , Config ),
3799
+
3800
+ % % Reject messages in the following order: 2, 3, 4, 1, 5
3801
+ ok = amqp10_client_session :disposition (
3802
+ Receiver1 ,
3803
+ amqp10_msg :delivery_id (Msg2 ),
3804
+ amqp10_msg :delivery_id (Msg4 ),
3805
+ true ,
3806
+ rejected ),
3807
+ ok = amqp10_client_session :disposition (
3808
+ Receiver1 ,
3809
+ amqp10_msg :delivery_id (Msg1 ),
3810
+ amqp10_msg :delivery_id (Msg5 ),
3811
+ true ,
3812
+ rejected ),
3813
+
3814
+ assert_messages (QName1 , 0 , 0 , Config ),
3815
+ % % All 5 messages should be in the dead letter queue.
3816
+ assert_messages (QName2 , 5 , 0 , Config ),
3817
+
3818
+ {ok , MsgDead2 } = amqp10_client :get_msg (Receiver2 ),
3819
+ {ok , MsgDead3 } = amqp10_client :get_msg (Receiver2 ),
3820
+ {ok , MsgDead4 } = amqp10_client :get_msg (Receiver2 ),
3821
+ {ok , MsgDead1 } = amqp10_client :get_msg (Receiver2 ),
3822
+ {ok , MsgDead5 } = amqp10_client :get_msg (Receiver2 ),
3823
+ assert_messages (QName2 , 5 , 5 , Config ),
3824
+
3825
+ % % Messages should be dead lettered in the order we rejected.
3826
+ ? assertEqual (<<" 2" >>, amqp10_msg :body_bin (MsgDead2 )),
3827
+ ? assertEqual (<<" 3" >>, amqp10_msg :body_bin (MsgDead3 )),
3828
+ ? assertEqual (<<" 4" >>, amqp10_msg :body_bin (MsgDead4 )),
3829
+ ? assertEqual (<<" 1" >>, amqp10_msg :body_bin (MsgDead1 )),
3830
+ ? assertEqual (<<" 5" >>, amqp10_msg :body_bin (MsgDead5 )),
3831
+
3832
+ % % Accept all messages in the dead letter queue.
3833
+ ok = amqp10_client_session :disposition (
3834
+ Receiver2 ,
3835
+ amqp10_msg :delivery_id (MsgDead2 ),
3836
+ amqp10_msg :delivery_id (MsgDead5 ),
3837
+ true ,
3838
+ accepted ),
3839
+ assert_messages (QName2 , 0 , 0 , Config ),
3840
+
3841
+ ok = amqp10_client :detach_link (Receiver1 ),
3842
+ ok = amqp10_client :detach_link (Receiver2 ),
3843
+ ok = amqp10_client :detach_link (Sender ),
3844
+ {ok , #{message_count := 0 }} = rabbitmq_amqp_client :delete_queue (LinkPair , QName1 ),
3845
+ {ok , #{message_count := 0 }} = rabbitmq_amqp_client :delete_queue (LinkPair , QName2 ),
3846
+ ok = rabbitmq_amqp_client :detach_management_link_pair_sync (LinkPair ),
3847
+ ok = end_session_sync (Session ),
3848
+ ok = amqp10_client :close_connection (Connection ).
3849
+
3750
3850
% % Dead letter from a quorum queue into a stream.
3751
3851
dead_letter_into_stream (Config ) ->
3752
3852
{Connection0 , Session0 , LinkPair0 } = init (0 , Config ),
@@ -3820,6 +3920,124 @@ dead_letter_into_stream(Config) ->
3820
3920
ok = amqp10_client :close_connection (Connection0 ),
3821
3921
ok = amqp10_client :close_connection (Connection1 ).
3822
3922
3923
+ accept_multiple_message_order_classic_queue (Config ) ->
3924
+ accept_multiple_message_order (<<" classic" >>, Config ).
3925
+
3926
+ accept_multiple_message_order_quorum_queue (Config ) ->
3927
+ accept_multiple_message_order (<<" quorum" >>, Config ).
3928
+
3929
+ accept_multiple_message_order (QType , Config ) ->
3930
+ QName = atom_to_binary (? FUNCTION_NAME ),
3931
+ Address = <<" /queue/" , QName /binary >>,
3932
+
3933
+ {Connection , Session , LinkPair } = init (Config ),
3934
+ QProps = #{arguments => #{<<" x-queue-type" >> => {utf8 , QType }}},
3935
+ {ok , #{type := QType }} = rabbitmq_amqp_client :declare_queue (LinkPair , QName , QProps ),
3936
+
3937
+ {ok , Sender } = amqp10_client :attach_sender_link (Session , <<" sender" >>, Address , settled ),
3938
+ ok = wait_for_credit (Sender ),
3939
+ [begin
3940
+ Bin = integer_to_binary (N ),
3941
+ Msg = amqp10_msg :new (Bin , Bin , true ),
3942
+ ok = amqp10_client :send_msg (Sender , Msg )
3943
+ end || N <- lists :seq (1 , 5 )],
3944
+ ok = amqp10_client :detach_link (Sender ),
3945
+ assert_messages (QName , 5 , 0 , Config ),
3946
+
3947
+ {ok , Receiver } = amqp10_client :attach_receiver_link (Session , <<" receiver" >>, QName , unsettled ),
3948
+ {ok , Msg1 } = amqp10_client :get_msg (Receiver ),
3949
+ {ok , Msg2 } = amqp10_client :get_msg (Receiver ),
3950
+ {ok , _Msg3 } = amqp10_client :get_msg (Receiver ),
3951
+ {ok , Msg4 } = amqp10_client :get_msg (Receiver ),
3952
+ {ok , Msg5 } = amqp10_client :get_msg (Receiver ),
3953
+ assert_messages (QName , 5 , 5 , Config ),
3954
+
3955
+ % % Accept messages out of order.
3956
+ ok = amqp10_client_session :disposition (
3957
+ Receiver ,
3958
+ amqp10_msg :delivery_id (Msg2 ),
3959
+ amqp10_msg :delivery_id (Msg4 ),
3960
+ true ,
3961
+ accepted ),
3962
+ assert_messages (QName , 2 , 2 , Config ),
3963
+
3964
+ ok = amqp10_client :accept_msg (Receiver , Msg5 ),
3965
+ assert_messages (QName , 1 , 1 , Config ),
3966
+
3967
+ ok = amqp10_client :accept_msg (Receiver , Msg1 ),
3968
+ assert_messages (QName , 0 , 0 , Config ),
3969
+
3970
+ ok = amqp10_client :detach_link (Receiver ),
3971
+ ? assertMatch ({ok , #{message_count := 0 }}, rabbitmq_amqp_client :delete_queue (LinkPair , QName )),
3972
+ ok = rabbitmq_amqp_client :detach_management_link_pair_sync (LinkPair ),
3973
+ ok = end_session_sync (Session ),
3974
+ ok = amqp10_client :close_connection (Connection ).
3975
+
3976
+ release_multiple_message_order_classic_queue (Config ) ->
3977
+ release_multiple_message_order (<<" classic" >>, Config ).
3978
+
3979
+ release_multiple_message_order_quorum_queue (Config ) ->
3980
+ release_multiple_message_order (<<" quorum" >>, Config ).
3981
+
3982
+ release_multiple_message_order (QType , Config ) ->
3983
+ QName = atom_to_binary (? FUNCTION_NAME ),
3984
+ Address = <<" /queue/" , QName /binary >>,
3985
+
3986
+ {Connection , Session , LinkPair } = init (Config ),
3987
+ QProps = #{arguments => #{<<" x-queue-type" >> => {utf8 , QType }}},
3988
+ {ok , #{type := QType }} = rabbitmq_amqp_client :declare_queue (LinkPair , QName , QProps ),
3989
+
3990
+ {ok , Sender } = amqp10_client :attach_sender_link (Session , <<" sender" >>, Address , settled ),
3991
+ ok = wait_for_credit (Sender ),
3992
+ [begin
3993
+ Bin = integer_to_binary (N ),
3994
+ Msg = amqp10_msg :new (Bin , Bin , true ),
3995
+ ok = amqp10_client :send_msg (Sender , Msg )
3996
+ end || N <- lists :seq (1 , 4 )],
3997
+ ok = amqp10_client :detach_link (Sender ),
3998
+ assert_messages (QName , 4 , 0 , Config ),
3999
+
4000
+ {ok , Receiver } = amqp10_client :attach_receiver_link (Session , <<" receiver" >>, QName , unsettled ),
4001
+ {ok , Msg1 } = amqp10_client :get_msg (Receiver ),
4002
+ {ok , Msg2 } = amqp10_client :get_msg (Receiver ),
4003
+ {ok , Msg3 } = amqp10_client :get_msg (Receiver ),
4004
+ {ok , Msg4 } = amqp10_client :get_msg (Receiver ),
4005
+ assert_messages (QName , 4 , 4 , Config ),
4006
+
4007
+ % % Release messages out of order.
4008
+ ok = amqp10_client_session :disposition (
4009
+ Receiver ,
4010
+ amqp10_msg :delivery_id (Msg2 ),
4011
+ amqp10_msg :delivery_id (Msg3 ),
4012
+ true ,
4013
+ released ),
4014
+ % % Both messages should be requeued and redelivered.
4015
+ assert_messages (QName , 4 , 2 , Config ),
4016
+
4017
+ {ok , Msg2b } = amqp10_client :get_msg (Receiver ),
4018
+ {ok , Msg3b } = amqp10_client :get_msg (Receiver ),
4019
+ assert_messages (QName , 4 , 4 , Config ),
4020
+ ? assertEqual ([<<" 2" >>], amqp10_msg :body (Msg2b )),
4021
+ ? assertEqual ([<<" 3" >>], amqp10_msg :body (Msg3b )),
4022
+
4023
+ ok = amqp10_client_session :disposition (
4024
+ Receiver ,
4025
+ amqp10_msg :delivery_id (Msg4 ),
4026
+ amqp10_msg :delivery_id (Msg3b ),
4027
+ true ,
4028
+ accepted ),
4029
+ assert_messages (QName , 1 , 1 , Config ),
4030
+
4031
+ ok = amqp10_client :accept_msg (Receiver , Msg1 ),
4032
+ assert_messages (QName , 0 , 0 , Config ),
4033
+
4034
+ ok = amqp10_client :detach_link (Receiver ),
4035
+ ? assertMatch ({ok , #{message_count := 0 }}, rabbitmq_amqp_client :delete_queue (LinkPair , QName )),
4036
+ ok = rabbitmq_amqp_client :detach_management_link_pair_sync (LinkPair ),
4037
+ ok = end_session_sync (Session ),
4038
+ ok = amqp10_client :close_connection (Connection ).
4039
+
4040
+
3823
4041
% % This test asserts the following §3.2 requirement:
3824
4042
% % "The bare message is immutable within the AMQP network. That is, none of the sections can be
3825
4043
% % changed by any node acting as an AMQP intermediary. If a section of the bare message is
@@ -4359,6 +4577,7 @@ tcp_back_pressure_rabbitmq_internal_flow(QType, Config) ->
4359
4577
ok = end_session_sync (Session ),
4360
4578
ok = amqp10_client :close_connection (Connection ).
4361
4579
4580
+
4362
4581
% % internal
4363
4582
% %
4364
4583
@@ -4592,13 +4811,16 @@ send_messages_with_group_id(Sender, N, GroupId) ->
4592
4811
end || I <- lists :seq (1 , N )].
4593
4812
4594
4813
assert_messages (QNameBin , NumTotalMsgs , NumUnackedMsgs , Config ) ->
4814
+ assert_messages (QNameBin , NumTotalMsgs , NumUnackedMsgs , Config , 0 ).
4815
+
4816
+ assert_messages (QNameBin , NumTotalMsgs , NumUnackedMsgs , Config , Node ) ->
4595
4817
Vhost = ? config (rmq_vhost , Config ),
4596
4818
eventually (
4597
4819
? _assertEqual (
4598
4820
lists :sort ([{messages , NumTotalMsgs }, {messages_unacknowledged , NumUnackedMsgs }]),
4599
4821
begin
4600
- {ok , Q } = rpc (Config , rabbit_amqqueue , lookup , [QNameBin , Vhost ]),
4601
- Infos = rpc (Config , rabbit_amqqueue , info , [Q , [messages , messages_unacknowledged ]]),
4822
+ {ok , Q } = rpc (Config , Node , rabbit_amqqueue , lookup , [QNameBin , Vhost ]),
4823
+ Infos = rpc (Config , Node , rabbit_amqqueue , info , [Q , [messages , messages_unacknowledged ]]),
4602
4824
lists :sort (Infos )
4603
4825
end
4604
4826
), 500 , 5 ).
0 commit comments