@@ -34,7 +34,8 @@ groups() ->
3434 autodelete ,
3535 validation ,
3636 security_validation ,
37- get_connection_name
37+ get_connection_name ,
38+ credit_flow
3839 ]},
3940
4041 {quorum_queue_tests , [], [
@@ -439,6 +440,67 @@ get_connection_name(_Config) ->
439440 <<" Shovel" >> = rabbit_shovel_worker :get_connection_name ({one , two , three }),
440441 <<" Shovel" >> = rabbit_shovel_worker :get_connection_name (<<" anything else" >>).
441442
443+ credit_flow (Config ) ->
444+ OrigCredit = set_default_credit (Config , {20 , 10 }),
445+
446+ with_ch (Config ,
447+ fun (Ch ) ->
448+ amqp_channel :call (Ch , # 'confirm.select' {}),
449+ amqp_channel :call (Ch , # 'queue.declare' {queue = <<" src" >>}),
450+ % % Send larger payloads to fill up the socket buffers quicker
451+ Payload = binary :copy (<<" hello" >>, 1000 ),
452+ publish_count (Ch , <<>>, <<" src" >>, Payload , 1000 ),
453+ amqp_channel :wait_for_confirms (Ch ),
454+
455+ OrigLimit = set_vm_memory_high_watermark (Config , 0.00000001 ),
456+ % % Let connection block.
457+ timer :sleep (100 ),
458+
459+ try
460+ shovel_test_utils :set_param_nowait (
461+ Config ,
462+ <<" test" >>, [{<<" src-queue" >>, <<" src" >>},
463+ {<<" dest-queue" >>, <<" dest" >>},
464+ {<<" src-prefetch-count" >>, 50 },
465+ {<<" ack-mode" >>, <<" on-publish" >>},
466+ {<<" src-delete-after" >>, <<" never" >>}]),
467+ shovel_test_utils :await_shovel (Config , <<" test" >>),
468+
469+ % % There should be only one process with a message buildup
470+ [{WriterPid , MQLen , _ }, {_ , 0 , _ }] =
471+ rabbit_ct_broker_helpers :rpc (
472+ Config , 0 , recon , proc_count , [message_queue_len , 2 ]),
473+
474+ % % The writer process should have only a limited message queue,
475+ % % but it is hard to exactly know how long.
476+ % % (There are some `inet_reply' messages from the
477+ % % inet driver, and some messages from the channel,
478+ % % we estimate the later to be less than double the
479+ % % initial credit)
480+ {messages , Msgs } = rabbit_ct_broker_helpers :rpc (
481+ Config , 0 , erlang , process_info , [WriterPid , messages ]),
482+ CmdLen = length ([Msg || Msg <- Msgs ,
483+ element (1 , Msg ) =:= send_command_flow ]),
484+ case {writer_msg_queue_len , CmdLen , MQLen } of
485+ _ when CmdLen < 2 * 20 -> ok
486+ end ,
487+
488+ ExpDest = 0 ,
489+ # 'queue.declare_ok' {message_count = ExpDest } =
490+ amqp_channel :call (Ch , # 'queue.declare' {queue = <<" dest" >>,
491+ durable = true }),
492+ # 'queue.declare_ok' {message_count = SrcCnt } =
493+ amqp_channel :call (Ch , # 'queue.declare' {queue = <<" src" >>}),
494+
495+ % % Most messages should still be in the queue either ready or unacked
496+ case {src_queue_message_count , SrcCnt } of
497+ _ when 0 < SrcCnt andalso SrcCnt < 1000 - MQLen -> ok
498+ end
499+ after
500+ set_vm_memory_high_watermark (Config , OrigLimit ),
501+ set_default_credit (Config , OrigCredit )
502+ end
503+ end ).
442504
443505% %----------------------------------------------------------------------------
444506
@@ -541,3 +603,21 @@ await_autodelete1(_Config, Name) ->
541603shovels_from_parameters () ->
542604 L = rabbit_runtime_parameters :list (<<" /" >>, <<" shovel" >>),
543605 [rabbit_misc :pget (name , Shovel ) || Shovel <- L ].
606+
607+ set_default_credit (Config , Value ) ->
608+ {ok , OrigValue } =
609+ rabbit_ct_broker_helpers :rpc (
610+ Config , 0 , application , get_env , [rabbit , credit_flow_default_credit ]),
611+ ok =
612+ rabbit_ct_broker_helpers :rpc (
613+ Config , 0 , application , set_env , [rabbit , credit_flow_default_credit , Value ]),
614+ OrigValue .
615+
616+ set_vm_memory_high_watermark (Config , Limit ) ->
617+ OrigLimit =
618+ rabbit_ct_broker_helpers :rpc (
619+ Config , 0 , vm_memory_monitor , get_vm_memory_high_watermark , []),
620+ ok =
621+ rabbit_ct_broker_helpers :rpc (
622+ Config , 0 , vm_memory_monitor , set_vm_memory_high_watermark , [Limit ]),
623+ OrigLimit .
0 commit comments