@@ -96,6 +96,7 @@ groups() ->
96
96
force_shrink_member_to_current_member ,
97
97
force_all_queues_shrink_member_to_current_member ,
98
98
force_vhost_queues_shrink_member_to_current_member ,
99
+ policy_repair ,
99
100
gh_12635
100
101
]
101
102
++ all_tests ()},
@@ -1303,20 +1304,175 @@ force_vhost_queues_shrink_member_to_current_member(Config) ->
1303
1304
? assertEqual (3 , length (Nodes0 ))
1304
1305
end || Q <- QQs , VHost <- VHosts ].
1305
1306
1307
+
1308
+ % Tests that, if the process of a QQ is dead in the moment of declaring a policy
1309
+ % that affects such queue, when the process is made available again, the policy
1310
+ % will eventually get applied. (https://github.com/rabbitmq/rabbitmq-server/issues/7863)
1311
+ policy_repair (Config ) ->
1312
+ [Server0 , _Server1 , _Server2 ] = Servers =
1313
+ rabbit_ct_broker_helpers :get_node_configs (Config , nodename ),
1314
+ Ch = rabbit_ct_client_helpers :open_channel (Config , Server0 ),
1315
+ # 'confirm.select_ok' {} = amqp_channel :call (Ch , # 'confirm.select' {}),
1316
+
1317
+ QQ = ? config (queue_name , Config ),
1318
+ ? assertEqual ({'queue.declare_ok' , QQ , 0 , 0 },
1319
+ declare (Ch , QQ , [{<<" x-queue-type" >>, longstr , <<" quorum" >>}])),
1320
+ RaName = ra_name (QQ ),
1321
+ ExpectedMaxLength1 = 10 ,
1322
+ Priority1 = 1 ,
1323
+ ok = rabbit_ct_broker_helpers :rpc (
1324
+ Config ,
1325
+ 0 ,
1326
+ rabbit_policy ,
1327
+ set ,
1328
+ [
1329
+ <<" /" >>,
1330
+ <<QQ /binary , " _1" >>,
1331
+ QQ ,
1332
+ [{<<" max-length" >>, ExpectedMaxLength1 }, {<<" overflow" >>, <<" reject-publish" >>}],
1333
+ Priority1 ,
1334
+ <<" quorum_queues" >>,
1335
+ <<" acting-user" >>
1336
+ ]),
1337
+
1338
+ % Wait for the policy to apply
1339
+ QueryFun = fun rabbit_fifo :overview /1 ,
1340
+ ? awaitMatch ({ok , {_ , #{config := #{max_length := ExpectedMaxLength1 }}}, _ },
1341
+ rpc :call (Server0 , ra , local_query , [RaName , QueryFun ]),
1342
+ ? DEFAULT_AWAIT ),
1343
+
1344
+ % Check the policy has been applied
1345
+ % Insert MaxLength1 + some messages but after consuming all messages only
1346
+ % MaxLength1 are retrieved.
1347
+ % Checking twice to ensure consistency
1348
+ publish_confirm_many (Ch , QQ , ExpectedMaxLength1 + 1 ),
1349
+ % +1 because QQs let one pass
1350
+ wait_for_messages_ready (Servers , RaName , ExpectedMaxLength1 + 1 ),
1351
+ fail = publish_confirm (Ch , QQ ),
1352
+ fail = publish_confirm (Ch , QQ ),
1353
+ consume_all (Ch , QQ ),
1354
+
1355
+ % Set higher priority policy, allowing more messages
1356
+ ExpectedMaxLength2 = 20 ,
1357
+ Priority2 = 2 ,
1358
+ ok = rabbit_ct_broker_helpers :rpc (
1359
+ Config ,
1360
+ 0 ,
1361
+ rabbit_policy ,
1362
+ set ,
1363
+ [
1364
+ <<" /" >>,
1365
+ <<QQ /binary , " _2" >>,
1366
+ QQ ,
1367
+ [{<<" max-length" >>, ExpectedMaxLength2 }, {<<" overflow" >>, <<" reject-publish" >>}],
1368
+ Priority2 ,
1369
+ <<" quorum_queues" >>,
1370
+ <<" acting-user" >>
1371
+ ]),
1372
+
1373
+ % Wait for the policy to apply
1374
+ ? awaitMatch ({ok , {_ , #{config := #{max_length := ExpectedMaxLength2 }}}, _ },
1375
+ rpc :call (Server0 , ra , local_query , [RaName , QueryFun ]),
1376
+ ? DEFAULT_AWAIT ),
1377
+
1378
+ % Check the policy has been applied
1379
+ % Insert MaxLength2 + some messages but after consuming all messages only
1380
+ % MaxLength2 are retrieved.
1381
+ % Checking twice to ensure consistency.
1382
+ % + 1 because QQs let one pass
1383
+ publish_confirm_many (Ch , QQ , ExpectedMaxLength2 + 1 ),
1384
+ wait_for_messages_ready (Servers , RaName , ExpectedMaxLength2 + 1 ),
1385
+ fail = publish_confirm (Ch , QQ ),
1386
+ fail = publish_confirm (Ch , QQ ),
1387
+ consume_all (Ch , QQ ),
1388
+
1389
+ % Ensure the queue process is unavailable
1390
+ lists :foreach (fun (Srv ) -> ensure_qq_proc_dead (Config , Srv , RaName ) end , Servers ),
1391
+
1392
+ % Add policy with higher priority, allowing even more messages.
1393
+ ExpectedMaxLength3 = 30 ,
1394
+ Priority3 = 3 ,
1395
+ ok = rabbit_ct_broker_helpers :rpc (
1396
+ Config ,
1397
+ 0 ,
1398
+ rabbit_policy ,
1399
+ set ,
1400
+ [
1401
+ <<" /" >>,
1402
+ <<QQ /binary , " _3" >>,
1403
+ QQ ,
1404
+ [{<<" max-length" >>, ExpectedMaxLength3 }, {<<" overflow" >>, <<" reject-publish" >>}],
1405
+ Priority3 ,
1406
+ <<" quorum_queues" >>,
1407
+ <<" acting-user" >>
1408
+ ]),
1409
+
1410
+ % Restart the queue process.
1411
+ {ok , Queue } =
1412
+ rabbit_ct_broker_helpers :rpc (
1413
+ Config ,
1414
+ 0 ,
1415
+ rabbit_amqqueue ,
1416
+ lookup ,
1417
+ [{resource , <<" /" >>, queue , QQ }]),
1418
+ lists :foreach (
1419
+ fun (Srv ) ->
1420
+ rabbit_ct_broker_helpers :rpc (
1421
+ Config ,
1422
+ Srv ,
1423
+ rabbit_quorum_queue ,
1424
+ recover ,
1425
+ [foo , [Queue ]]
1426
+ )
1427
+ end ,
1428
+ Servers ),
1429
+
1430
+ % Wait for the queue to be available again.
1431
+ lists :foreach (fun (Srv ) ->
1432
+ rabbit_ct_helpers :await_condition (
1433
+ fun () ->
1434
+ is_pid (
1435
+ rabbit_ct_broker_helpers :rpc (
1436
+ Config ,
1437
+ Srv ,
1438
+ erlang ,
1439
+ whereis ,
1440
+ [RaName ]))
1441
+ end )
1442
+ end ,
1443
+ Servers ),
1444
+
1445
+ % Wait for the policy to apply
1446
+ ? awaitMatch ({ok , {_ , #{config := #{max_length := ExpectedMaxLength3 }}}, _ },
1447
+ rpc :call (Server0 , ra , local_query , [RaName , QueryFun ]),
1448
+ ? DEFAULT_AWAIT ),
1449
+
1450
+ % Check the policy has been applied
1451
+ % Insert MaxLength3 + some messages but after consuming all messages only
1452
+ % MaxLength3 are retrieved.
1453
+ % Checking twice to ensure consistency.
1454
+ % + 1 because QQs let one pass
1455
+ publish_confirm_many (Ch , QQ , ExpectedMaxLength3 + 1 ),
1456
+ wait_for_messages_ready (Servers , RaName , ExpectedMaxLength3 + 1 ),
1457
+ fail = publish_confirm (Ch , QQ ),
1458
+ fail = publish_confirm (Ch , QQ ),
1459
+ consume_all (Ch , QQ ).
1460
+
1461
+
1306
1462
gh_12635 (Config ) ->
1307
1463
% https://github.com/rabbitmq/rabbitmq-server/issues/12635
1308
1464
[Server0 , _Server1 , Server2 ] =
1309
1465
rabbit_ct_broker_helpers :get_node_configs (Config , nodename ),
1310
1466
1311
1467
ok = rabbit_ct_broker_helpers :rpc (Config , 0 , application , set_env ,
1312
- [rabbit , quorum_min_checkpoint_interval , 1 ]),
1468
+ [rabbit , quorum_min_checkpoint_interval , 1 ]),
1313
1469
1314
1470
Ch0 = rabbit_ct_client_helpers :open_channel (Config , Server0 ),
1315
1471
# 'confirm.select_ok' {} = amqp_channel :call (Ch0 , # 'confirm.select' {}),
1316
1472
QQ = ? config (queue_name , Config ),
1317
1473
RaName = ra_name (QQ ),
1318
1474
? assertEqual ({'queue.declare_ok' , QQ , 0 , 0 },
1319
- declare (Ch0 , QQ , [{<<" x-queue-type" >>, longstr , <<" quorum" >>}])),
1475
+ declare (Ch0 , QQ , [{<<" x-queue-type" >>, longstr , <<" quorum" >>}])),
1320
1476
1321
1477
% % stop member to simulate slow or down member
1322
1478
ok = rpc :call (Server2 , ra , stop_server , [quorum_queues , {RaName , Server2 }]),
@@ -1327,10 +1483,10 @@ gh_12635(Config) ->
1327
1483
% % force a checkpoint on leader
1328
1484
ok = rpc :call (Server0 , ra , cast_aux_command , [{RaName , Server0 }, force_checkpoint ]),
1329
1485
rabbit_ct_helpers :await_condition (
1330
- fun () ->
1331
- {ok , #{log := Log }, _ } = rpc :call (Server0 , ra , member_overview , [{RaName , Server0 }]),
1332
- undefined =/= maps :get (latest_checkpoint_index , Log )
1333
- end ),
1486
+ fun () ->
1487
+ {ok , #{log := Log }, _ } = rpc :call (Server0 , ra , member_overview , [{RaName , Server0 }]),
1488
+ undefined =/= maps :get (latest_checkpoint_index , Log )
1489
+ end ),
1334
1490
1335
1491
% % publish 1 more message
1336
1492
publish_confirm (Ch0 , QQ ),
@@ -1346,10 +1502,10 @@ gh_12635(Config) ->
1346
1502
# 'queue.purge_ok' {} = amqp_channel :call (Ch0 , # 'queue.purge' {queue = QQ }),
1347
1503
1348
1504
rabbit_ct_helpers :await_condition (
1349
- fun () ->
1350
- {ok , #{log := Log }, _ } = rpc :call (Server0 , ra , member_overview , [{RaName , Server0 }]),
1351
- undefined =/= maps :get (snapshot_index , Log )
1352
- end ),
1505
+ fun () ->
1506
+ {ok , #{log := Log }, _ } = rpc :call (Server0 , ra , member_overview , [{RaName , Server0 }]),
1507
+ undefined =/= maps :get (snapshot_index , Log )
1508
+ end ),
1353
1509
% % restart the down member
1354
1510
ok = rpc :call (Server2 , ra , restart_server , [quorum_queues , {RaName , Server2 }]),
1355
1511
Pid2 = rpc :call (Server2 , erlang , whereis , [RaName ]),
@@ -1359,11 +1515,12 @@ gh_12635(Config) ->
1359
1515
{'DOWN' ,Ref , process ,_ , _ } ->
1360
1516
ct :fail (" unexpected DOWN" )
1361
1517
after 500 ->
1362
- ok
1518
+ ok
1363
1519
end ,
1364
1520
flush (1 ),
1365
1521
ok .
1366
1522
1523
+
1367
1524
priority_queue_fifo (Config ) ->
1368
1525
% % testing: if hi priority messages are published before lo priority
1369
1526
% % messages they are always consumed first (fifo)
@@ -4397,3 +4554,28 @@ lists_interleave([Item | Items], List)
4397
4554
{Left , Right } = lists :split (2 , List ),
4398
4555
Left ++ [Item | lists_interleave (Items , Right )].
4399
4556
4557
+ publish_confirm_many (Ch , Queue , Count ) ->
4558
+ lists :foreach (fun (_ ) -> publish_confirm (Ch , Queue ) end , lists :seq (1 , Count )).
4559
+
4560
+ consume_all (Ch , QQ ) ->
4561
+ Consume = fun C (Acc ) ->
4562
+ case amqp_channel :call (Ch , # 'basic.get' {queue = QQ }) of
4563
+ {# 'basic.get_ok' {}, Msg } ->
4564
+ C ([Msg | Acc ]);
4565
+ _ ->
4566
+ Acc
4567
+ end
4568
+ end ,
4569
+ Consume ([]).
4570
+
4571
+ ensure_qq_proc_dead (Config , Server , RaName ) ->
4572
+ case rabbit_ct_broker_helpers :rpc (Config , Server , erlang , whereis , [RaName ]) of
4573
+ undefined ->
4574
+ ok ;
4575
+ Pid ->
4576
+ rabbit_ct_broker_helpers :rpc (Config , Server , erlang , exit , [Pid , kill ]),
4577
+ % % Give some time for the supervisor to restart the process
4578
+ timer :sleep (500 ),
4579
+ ensure_qq_proc_dead (Config , Server , RaName )
4580
+ end .
4581
+
0 commit comments