@@ -41,7 +41,8 @@ groups() ->
41
41
[
42
42
reliable_send_receive_with_outcomes_classic_queue ,
43
43
reliable_send_receive_with_outcomes_quorum_queue ,
44
- modified ,
44
+ modified_classic_queue ,
45
+ modified_quorum_queue ,
45
46
sender_settle_mode_unsettled ,
46
47
sender_settle_mode_unsettled_fanout ,
47
48
sender_settle_mode_mixed ,
@@ -403,11 +404,59 @@ reliable_send_receive(QType, Outcome, Config) ->
403
404
ok = end_session_sync (Session2 ),
404
405
ok = amqp10_client :close_connection (Connection2 ).
405
406
406
- % % This test case doesn't expect the correct AMQP spec behavivour.
407
- % % We know that RabbitMQ doesn't implement the modified outcome correctly.
408
- % % Here, we test RabbitMQ's workaround behaviour:
409
- % % RabbitMQ discards if undeliverable-here is true. Otherwise, RabbitMQ requeues.
410
- modified (Config ) ->
407
+ % % We test the modified outcome with classic queues.
408
+ % % We expect that classic queues implement field undeliverable-here incorrectly
409
+ % % by discarding (if true) or requeueing (if false).
410
+ % % Fields delivery-failed and message-annotations are not implemented.
411
+ modified_classic_queue (Config ) ->
412
+ QName = atom_to_binary (? FUNCTION_NAME ),
413
+ {Connection , Session , LinkPair } = init (Config ),
414
+ {ok , #{type := <<" classic" >>}} = rabbitmq_amqp_client :declare_queue (
415
+ LinkPair , QName ,
416
+ #{arguments => #{<<" x-queue-type" >> => {utf8 , <<" classic" >>}}}),
417
+ Address = rabbitmq_amqp_address :queue (QName ),
418
+ {ok , Sender } = amqp10_client :attach_sender_link (Session , <<" sender" >>, Address ),
419
+ ok = wait_for_credit (Sender ),
420
+
421
+ Msg1 = amqp10_msg :new (<<" tag1" >>, <<" m1" >>, true ),
422
+ Msg2 = amqp10_msg :new (<<" tag2" >>, <<" m2" >>, true ),
423
+ ok = amqp10_client :send_msg (Sender , Msg1 ),
424
+ ok = amqp10_client :send_msg (Sender , Msg2 ),
425
+ ok = amqp10_client :detach_link (Sender ),
426
+
427
+ {ok , Receiver } = amqp10_client :attach_receiver_link (Session , <<" receiver" >>, Address , unsettled ),
428
+
429
+ {ok , M1 } = amqp10_client :get_msg (Receiver ),
430
+ ? assertEqual ([<<" m1" >>], amqp10_msg :body (M1 )),
431
+ ok = amqp10_client :settle_msg (Receiver , M1 , {modified , false , true , #{}}),
432
+
433
+ {ok , M2a } = amqp10_client :get_msg (Receiver ),
434
+ ? assertEqual ([<<" m2" >>], amqp10_msg :body (M2a )),
435
+ ok = amqp10_client :settle_msg (Receiver , M2a ,
436
+ {modified , false , false , #{}}),
437
+
438
+ {ok , M2b } = amqp10_client :get_msg (Receiver ),
439
+ ? assertEqual ([<<" m2" >>], amqp10_msg :body (M2b )),
440
+ ok = amqp10_client :settle_msg (Receiver , M2b ,
441
+ {modified , true , false , #{<<" x-opt-key" >> => <<" val" >>}}),
442
+
443
+ {ok , M2c } = amqp10_client :get_msg (Receiver ),
444
+ ? assertEqual ([<<" m2" >>], amqp10_msg :body (M2c )),
445
+ ok = amqp10_client :settle_msg (Receiver , M2c , modified ),
446
+
447
+ ok = amqp10_client :detach_link (Receiver ),
448
+ ? assertMatch ({ok , #{message_count := 1 }},
449
+ rabbitmq_amqp_client :delete_queue (LinkPair , QName )),
450
+ ok = rabbitmq_amqp_client :detach_management_link_pair_sync (LinkPair ),
451
+ ok = end_session_sync (Session ),
452
+ ok = amqp10_client :close_connection (Connection ).
453
+
454
+ % % We test the modified outcome with quorum queues.
455
+ % % We expect that quorum queues implement field
456
+ % % * delivery-failed correctly
457
+ % % * undeliverable-here incorrectly by discarding (if true) or requeueing (if false)
458
+ % % * message-annotations correctly
459
+ modified_quorum_queue (Config ) ->
411
460
QName = atom_to_binary (? FUNCTION_NAME ),
412
461
{Connection , Session , LinkPair } = init (Config ),
413
462
{ok , #{type := <<" quorum" >>}} = rabbitmq_amqp_client :declare_queue (
@@ -427,34 +476,53 @@ modified(Config) ->
427
476
428
477
{ok , M1 } = amqp10_client :get_msg (Receiver ),
429
478
? assertEqual ([<<" m1" >>], amqp10_msg :body (M1 )),
430
- ? assertEqual (0 , amqp10_msg :header (delivery_count , M1 )),
479
+ ? assertMatch (#{delivery_count := 0 ,
480
+ first_acquirer := true },
481
+ amqp10_msg :headers (M1 )),
482
+ ok = amqp10_client :settle_msg (Receiver , M1 , {modified , false , true , #{}}),
431
483
432
- ok = amqp10_client :settle_msg (Receiver , M1 , {modified , false ,
433
- _UndeliverableHere = true , #{}}),
434
484
{ok , M2a } = amqp10_client :get_msg (Receiver ),
435
485
? assertEqual ([<<" m2" >>], amqp10_msg :body (M2a )),
436
- ? assertEqual (0 , amqp10_msg :header (delivery_count , M2a )),
437
-
486
+ ? assertMatch (#{delivery_count := 0 ,
487
+ first_acquirer := true },
488
+ amqp10_msg :headers (M2a )),
438
489
ok = amqp10_client :settle_msg (Receiver , M2a , {modified , false , false , #{}}),
490
+
439
491
{ok , M2b } = amqp10_client :get_msg (Receiver ),
440
492
? assertEqual ([<<" m2" >>], amqp10_msg :body (M2b )),
441
- ? assertEqual (0 , amqp10_msg :header (delivery_count , M2b )),
442
-
493
+ ? assertMatch (#{delivery_count := 0 ,
494
+ first_acquirer := false },
495
+ amqp10_msg :headers (M2b )),
443
496
ok = amqp10_client :settle_msg (Receiver , M2b , {modified , true , false , #{}}),
497
+
444
498
{ok , M2c } = amqp10_client :get_msg (Receiver ),
445
- ? assertEqual (1 , amqp10_msg :header (delivery_count , M2c )),
499
+ ? assertMatch (#{delivery_count := 1 ,
500
+ first_acquirer := false },
501
+ amqp10_msg :headers (M2c )),
446
502
? assertEqual ([<<" m2" >>], amqp10_msg :body (M2c )),
447
-
448
-
449
503
ok = amqp10_client :settle_msg (Receiver , M2c ,
450
504
{modified , true , false ,
451
- #{<<" x-opt-key" >> => <<" val" >>}}),
505
+ #{<<" x-opt-key" >> => <<" val 1 " >>}}),
452
506
453
507
{ok , M2d } = amqp10_client :get_msg (Receiver ),
454
508
? assertEqual ([<<" m2" >>], amqp10_msg :body (M2d )),
455
- ? assertEqual (2 , amqp10_msg :header (delivery_count , M2d )),
456
- ? assertMatch (#{<<" x-opt-key" >> := <<" val" >>}, amqp10_msg :message_annotations (M2d )),
457
- ok = amqp10_client :settle_msg (Receiver , M2d , modified ),
509
+ ? assertMatch (#{delivery_count := 2 ,
510
+ first_acquirer := false },
511
+ amqp10_msg :headers (M2d )),
512
+ ? assertMatch (#{<<" x-opt-key" >> := <<" val 1" >>}, amqp10_msg :message_annotations (M2d )),
513
+ ok = amqp10_client :settle_msg (Receiver , M2d ,
514
+ {modified , false , false ,
515
+ #{<<" x-opt-key" >> => <<" val 2" >>,
516
+ <<" x-other" >> => 99 }}),
517
+
518
+ {ok , M2e } = amqp10_client :get_msg (Receiver ),
519
+ ? assertEqual ([<<" m2" >>], amqp10_msg :body (M2e )),
520
+ ? assertMatch (#{delivery_count := 2 ,
521
+ first_acquirer := false },
522
+ amqp10_msg :headers (M2e )),
523
+ ? assertMatch (#{<<" x-opt-key" >> := <<" val 2" >>,
524
+ <<" x-other" >> := 99 }, amqp10_msg :message_annotations (M2e )),
525
+ ok = amqp10_client :settle_msg (Receiver , M2e , modified ),
458
526
459
527
ok = amqp10_client :detach_link (Receiver ),
460
528
? assertMatch ({ok , #{message_count := 1 }},
@@ -4429,6 +4497,7 @@ dead_letter_reject(Config) ->
4429
4497
QName1 ,
4430
4498
#{arguments => #{<<" x-queue-type" >> => {utf8 , <<" quorum" >>},
4431
4499
<<" x-message-ttl" >> => {ulong , 20 },
4500
+ <<" x-overflow" >> => {utf8 , <<" reject-publish" >>},
4432
4501
<<" x-dead-letter-strategy" >> => {utf8 , <<" at-least-once" >>},
4433
4502
<<" x-dead-letter-exchange" >> => {utf8 , <<>>},
4434
4503
<<" x-dead-letter-routing-key" >> => {utf8 , QName2 }
@@ -4463,22 +4532,22 @@ dead_letter_reject(Config) ->
4463
4532
? assertMatch (#{delivery_count := 0 ,
4464
4533
first_acquirer := true }, amqp10_msg :headers (Msg1 )),
4465
4534
ok = amqp10_client :settle_msg (Receiver , Msg1 , rejected ),
4535
+
4466
4536
{ok , Msg2 } = amqp10_client :get_msg (Receiver ),
4467
4537
? assertMatch (#{delivery_count := 1 ,
4468
4538
first_acquirer := false }, amqp10_msg :headers (Msg2 )),
4469
4539
ok = amqp10_client :settle_msg (Receiver , Msg2 ,
4470
4540
{modified , true , true ,
4471
4541
#{<<" x-opt-thekey" >> => <<" val" >>}}),
4542
+
4472
4543
{ok , Msg3 } = amqp10_client :get_msg (Receiver ),
4473
4544
? assertMatch (#{delivery_count := 2 ,
4474
4545
first_acquirer := false }, amqp10_msg :headers (Msg3 )),
4475
- ? assertMatch (#{<<" x-opt-thekey" >> := <<" val" >>},
4476
- amqp10_msg :message_annotations (Msg3 )),
4477
- ok = amqp10_client :settle_msg (Receiver , Msg3 , accepted ),
4478
4546
? assertEqual (Body , amqp10_msg :body_bin (Msg3 )),
4479
4547
Annotations = amqp10_msg :message_annotations (Msg3 ),
4480
4548
? assertMatch (
4481
- #{<<" x-first-death-queue" >> := QName1 ,
4549
+ #{<<" x-opt-thekey" >> := <<" val" >>,
4550
+ <<" x-first-death-queue" >> := QName1 ,
4482
4551
<<" x-first-death-exchange" >> := <<>>,
4483
4552
<<" x-first-death-reason" >> := <<" expired" >>,
4484
4553
<<" x-last-death-queue" >> := QName1 ,
@@ -4516,6 +4585,7 @@ dead_letter_reject(Config) ->
4516
4585
]} = D3 ,
4517
4586
? assertEqual ([Ts1 , Ts3 , Ts5 , Ts4 , Ts6 , Ts2 ],
4518
4587
lists :sort ([Ts1 , Ts2 , Ts3 , Ts4 , Ts5 , Ts6 ])),
4588
+ ok = amqp10_client :settle_msg (Receiver , Msg3 , accepted ),
4519
4589
4520
4590
ok = amqp10_client :detach_link (Receiver ),
4521
4591
ok = amqp10_client :detach_link (Sender ),
0 commit comments