import java.util.*; /** * CWE-407 unit tests for RabbitMQ rabbit_fifo.erl defects. * * rabbitmq-0001: deps/rabbit/src/rabbit_fifo.erl maybe_queue_consumer() * priority_queue:member(Key, ServiceQueue) — O(C) linear scan per message dispatch. * Called from update_or_remove_con after checkout_one pops the consumer; * the consumer is NEVER in SQ1 at that point — the scan is 100% wasted work. * Fix: maintain a shadow map #{consumer_key => true} for O(1) maps:is_key(). * * rabbitmq-0002: deps/rabbit/src/rabbit_queue_consumers.erl is_blocked() * priority_queue:member(Consumer, BlockedConsumers) — O(B) per delivery attempt * in single-active-consumer mode. * Fix: shadow set #{consumer => true} in #cr{} for O(1) maps:is_key(). */ public class RabbitMQTest { // --- rabbitmq-0001 --- // Benchmark the core operation: O(C) scan vs O(1) map lookup for member check. // In the post-checkout path the consumer is NEVER in the service queue — // the scan always does a full traversal and returns false (100% wasted). static boolean pqMember_scan(List pq, int key) { for (int k : pq) { // O(C) — defect: full scan, always false post-checkout if (k == key) return true; } return false; } static boolean pqMember_map(Set sqSet, int key) { return sqSet.contains(key); // O(1) — fix } static void testRabbitMQ0001() throws Exception { int C = 500; // consumers in service queue List sq = new ArrayList<>(C); Set sqSet = new HashSet<>(C); for (int i = 1; i <= C; i++) { sq.add(i); sqSet.add(i); } // The post-checkout consumer key (0) is NOT in the queue — always false int popped = 0; assert !pqMember_scan(sq, popped) : "popped consumer must not be in SQ"; assert !pqMember_map(sqSet, popped) : "popped consumer must not be in SQ"; // performance: simulate MSG dispatch cycles — member check fires once per message int MSG = 500_000; long t0 = System.nanoTime(); for (int m = 0; m < MSG; m++) pqMember_scan(sq, popped); long tScan = System.nanoTime() - t0; t0 = System.nanoTime(); for (int m = 0; m < MSG; m++) pqMember_map(sqSet, popped); long tMap = System.nanoTime() - t0; double ratio = (double) tScan / tMap; System.out.printf("rabbitmq-0001: scan=%.3fs map=%.3fs ratio=%.1f×%n", tScan / 1e9, tMap / 1e9, ratio); assert ratio > 10 : "Expected >10× speedup, got " + ratio; System.out.println("PASS rabbitmq-0001"); } // --- rabbitmq-0002 --- static boolean isBlocked_pqMember(List blocked, int consumer) { return blocked.contains(consumer); // O(B) — defect } static boolean isBlocked_mapKey(Set blockedSet, int consumer) { return blockedSet.contains(consumer); // O(1) — fix } static void testRabbitMQ0002() throws Exception { int B = 300; // blocked consumers (high-prefetch setup) int MSG = 100_000; List blocked = new ArrayList<>(B); Set blockedSet = new HashSet<>(B); for (int i = 0; i < B; i++) { blocked.add(i); blockedSet.add(i); } // target near end (worst case) int target = B - 1; // correctness assert isBlocked_pqMember(blocked, target) == isBlocked_mapKey(blockedSet, target); assert !isBlocked_pqMember(blocked, B + 99) && !isBlocked_mapKey(blockedSet, B + 99); long t0 = System.nanoTime(); for (int r = 0; r < MSG; r++) isBlocked_pqMember(blocked, target); long tMember = System.nanoTime() - t0; t0 = System.nanoTime(); for (int r = 0; r < MSG; r++) isBlocked_mapKey(blockedSet, target); long tMap = System.nanoTime() - t0; double ratio = (double) tMember / tMap; System.out.printf("rabbitmq-0002: member=%.3fs map=%.3fs ratio=%.1f×%n", tMember / 1e9, tMap / 1e9, ratio); assert ratio > 5 : "Expected >5× speedup, got " + ratio; System.out.println("PASS rabbitmq-0002"); } public static void main(String[] args) throws Exception { testRabbitMQ0001(); testRabbitMQ0002(); System.out.println("ALL PASS"); } }