@@ -116,7 +116,8 @@ groups() ->
116116 node_removal_is_not_quorum_critical ,
117117 select_nodes_with_least_replicas ,
118118 select_nodes_with_least_replicas_node_down ,
119- subscribe_from_each
119+ subscribe_from_each ,
120+ grow_queue
120121
121122
122123 ]},
@@ -1768,6 +1769,116 @@ dont_leak_file_handles(Config) ->
17681769 rabbit_ct_client_helpers :close_channel (C ),
17691770 ok .
17701771
1772+ grow_queue (Config ) ->
1773+ [Server0 , Server1 , Server2 , _Server3 , _Server4 ] =
1774+ rabbit_ct_broker_helpers :get_node_configs (Config , nodename ),
1775+
1776+ Ch = rabbit_ct_client_helpers :open_channel (Config , Server0 ),
1777+ QQ = ? config (queue_name , Config ),
1778+ AQ = ? config (alt_queue_name , Config ),
1779+ ? assertEqual ({'queue.declare_ok' , QQ , 0 , 0 },
1780+ declare (Ch , QQ , [{<<" x-queue-type" >>, longstr , <<" quorum" >>},
1781+ {<<" x-quorum-initial-group-size" >>, long , 5 }])),
1782+ ? assertEqual ({'queue.declare_ok' , AQ , 0 , 0 },
1783+ declare (Ch , AQ , [{<<" x-queue-type" >>, longstr , <<" quorum" >>},
1784+ {<<" x-quorum-initial-group-size" >>, long , 5 }])),
1785+
1786+ QQs = [QQ , AQ ],
1787+ MsgCount = 3 ,
1788+
1789+ [begin
1790+ RaName = ra_name (Q ),
1791+ rabbit_ct_client_helpers :publish (Ch , Q , MsgCount ),
1792+ wait_for_messages_ready ([Server0 ], RaName , MsgCount ),
1793+ {ok , Q0 } = rpc :call (Server0 , rabbit_amqqueue , lookup , [Q , <<" /" >>]),
1794+ #{nodes := Nodes0 } = amqqueue :get_type_state (Q0 ),
1795+ ? assertEqual (5 , length (Nodes0 ))
1796+ end || Q <- QQs ],
1797+
1798+ rabbit_ct_broker_helpers :rpc (Config , 0 , rabbit_quorum_queue ,
1799+ force_all_queues_shrink_member_to_current_member , []),
1800+
1801+ TargetClusterSize_1 = 1 ,
1802+ assert_grown_queues (QQs , Server0 , TargetClusterSize_1 , MsgCount ),
1803+
1804+ % % grow queues to node 'Server1'
1805+ TargetClusterSize_2 = 2 ,
1806+ Result1 = rpc :call (Server0 , rabbit_quorum_queue , grow , [Server1 , <<" /" >>, <<" .*" >>, all ]),
1807+ % % [{{resource,<<"/">>,queue,<<"grow_queue">>},{ok,2}},
1808+ % % {{resource,<<"/">>,queue,<<"grow_queue_alt">>},{ok,2}},...]
1809+ ? assert (lists :all (fun ({_ , {R , _ }}) -> R =:= ok end , Result1 )),
1810+ assert_grown_queues (QQs , Server0 , TargetClusterSize_2 , MsgCount ),
1811+
1812+ % % grow queues to quorum cluster size '2' has no effect
1813+ Result2 = rpc :call (Server0 , rabbit_quorum_queue , grow , [TargetClusterSize_2 , <<" /" >>, <<" .*" >>, all ]),
1814+ ? assertEqual ([], Result2 ),
1815+ assert_grown_queues (QQs , Server0 , TargetClusterSize_2 , MsgCount ),
1816+
1817+ % % grow queues to quorum cluster size '3'
1818+ TargetClusterSize_3 = 3 ,
1819+ Result3 = rpc :call (Server0 , rabbit_quorum_queue , grow , [TargetClusterSize_3 , <<" /" >>, <<" .*" >>, all , voter ]),
1820+ ? assert (lists :all (fun ({_ , {R , _ }}) -> R =:= ok end , Result3 )),
1821+ assert_grown_queues (QQs , Server0 , TargetClusterSize_3 , MsgCount ),
1822+
1823+ % % grow queues to quorum cluster size '5'
1824+ TargetClusterSize_5 = 5 ,
1825+ Result4 = rpc :call (Server0 , rabbit_quorum_queue , grow , [TargetClusterSize_5 , <<" /" >>, <<" .*" >>, all , voter ]),
1826+ ? assert (lists :all (fun ({_ , {R , _ }}) -> R =:= ok end , Result4 )),
1827+ assert_grown_queues (QQs , Server0 , TargetClusterSize_5 , MsgCount ),
1828+
1829+ % % shrink all queues again down to 1 member
1830+ rabbit_ct_broker_helpers :rpc (Config , 0 , rabbit_quorum_queue ,
1831+ force_all_queues_shrink_member_to_current_member , []),
1832+ assert_grown_queues (QQs , Server0 , TargetClusterSize_1 , MsgCount ),
1833+
1834+ % % grow queues to quorum cluster size > '5' (limit = 5).
1835+ TargetClusterSize_10 = 10 ,
1836+ Result5 = rpc :call (Server0 , rabbit_quorum_queue , grow , [TargetClusterSize_10 , <<" /" >>, <<" .*" >>, all ]),
1837+ ? assert (lists :all (fun ({_ , {R , _ }}) -> R =:= ok end , Result5 )),
1838+ assert_grown_queues (QQs , Server0 , TargetClusterSize_5 , MsgCount ),
1839+
1840+ % % shrink all queues again down to 1 member
1841+ rabbit_ct_broker_helpers :rpc (Config , 0 , rabbit_quorum_queue ,
1842+ force_all_queues_shrink_member_to_current_member , []),
1843+ assert_grown_queues (QQs , Server0 , TargetClusterSize_1 , MsgCount ),
1844+
1845+ % % attempt to grow queues to quorum cluster size < '0'.
1846+ BadTargetClusterSize = - 5 ,
1847+ ? assertEqual ({error , bad_quorum_cluster_size },
1848+ rpc :call (Server0 , rabbit_quorum_queue , grow , [BadTargetClusterSize , <<" /" >>, <<" .*" >>, all ])),
1849+
1850+ % % shrink all queues again down to 1 member
1851+ rabbit_ct_broker_helpers :rpc (Config , 0 , rabbit_quorum_queue ,
1852+ force_all_queues_shrink_member_to_current_member , []),
1853+ assert_grown_queues (QQs , Server0 , TargetClusterSize_1 , MsgCount ),
1854+
1855+ % % grow queues to node 'Server1': non_voter
1856+ rpc :call (Server0 , rabbit_quorum_queue , grow , [Server1 , <<" /" >>, <<" .*" >>, all , non_voter ]),
1857+ assert_grown_queues (QQs , Server0 , TargetClusterSize_2 , MsgCount ),
1858+
1859+ % % grow queues to node 'Server2': fail, non_voters found
1860+ Result6 = rpc :call (Server0 , rabbit_quorum_queue , grow , [Server2 , <<" /" >>, <<" .*" >>, all , voter ]),
1861+ % % [{{resource,<<"/">>,queue,<<"grow_queue">>},{error, 2, {error, non_voters_found}},
1862+ % % {{resource,<<"/">>,queue,<<"grow_queue_alt">>},{error, 2, {error, non_voters_found}},...]
1863+ ? assert (lists :all (
1864+ fun ({_ , Err }) -> Err =:= {error , TargetClusterSize_2 , {error , non_voters_found }} end , Result6 )),
1865+ assert_grown_queues (QQs , Server0 , TargetClusterSize_2 , MsgCount ),
1866+
1867+ % % grow queues to target quorum cluster size '5': fail, non_voters found
1868+ Result7 = rpc :call (Server0 , rabbit_quorum_queue , grow , [TargetClusterSize_5 , <<" /" >>, <<" .*" >>, all ]),
1869+ ? assert (lists :all (
1870+ fun ({_ , Err }) -> Err =:= {error , TargetClusterSize_2 , {error , non_voters_found }} end , Result7 )),
1871+ assert_grown_queues (QQs , Server0 , TargetClusterSize_2 , MsgCount ).
1872+
1873+ assert_grown_queues (Qs , Node , TargetClusterSize , MsgCount ) ->
1874+ [begin
1875+ RaName = ra_name (Q ),
1876+ wait_for_messages_ready ([Node ], RaName , MsgCount ),
1877+ {ok , Q0 } = rpc :call (Node , rabbit_amqqueue , lookup , [Q , <<" /" >>]),
1878+ #{nodes := Nodes0 } = amqqueue :get_type_state (Q0 ),
1879+ ? assertEqual (TargetClusterSize , length (Nodes0 ))
1880+ end || Q <- Qs ].
1881+
17711882gh_12635 (Config ) ->
17721883 % https://github.com/rabbitmq/rabbitmq-server/issues/12635
17731884 [Server0 , _Server1 , Server2 ] =
0 commit comments