|
38 | 38 | import static org.junit.Assert.assertTrue; |
39 | 39 | import static org.junit.Assert.assertFalse; |
40 | 40 | import static org.junit.Assert.assertEquals; |
| 41 | +import static org.junit.Assert.assertNotNull; |
41 | 42 |
|
42 | 43 | /** |
43 | 44 | * Tests correctness of the {@code ExpiryCheckEnabled} feature on |
@@ -246,9 +247,12 @@ public void testCustomLimitStrategyWithDefaultEvictionLeavesExpiryCheckEnabled() |
246 | 247 | * <li>Sending 250 messages with a very short TTL. |
247 | 248 | * <li>Waiting for all TTLs to elapse. |
248 | 249 | * <li>Sending one more message (triggers the code path). |
249 | | - * <li>Asserting that the broker's expired-message counter is 0 |
250 | | - * (no expiry scan ran) while the discarded counter is > 0 |
251 | | - * (normal eviction ran as expected). |
| 250 | + * <li>Asserting that the slow-consumer backlog was cleared by the normal |
| 251 | + * eviction strategy (discarded > 0) rather than the eager expiry scan, |
| 252 | + * i.e. eviction dominates any incidental expiry (expired < discarded). |
| 253 | + * The expired counter is not asserted to be exactly zero because the |
| 254 | + * always-on expiry paths (per-message dispatch check, client expired-acks) |
| 255 | + * may still expire a small, timing-dependent number of messages. |
252 | 256 | * </ol> |
253 | 257 | */ |
254 | 258 | @Test |
@@ -288,9 +292,28 @@ public void testExpiryCheckDisabledSkipsExpiredMessageScan() throws Exception { |
288 | 292 | Destination dest = broker.getDestination(new ActiveMQTopic("TEST.EXPIRY.DISABLED")); |
289 | 293 | long expiredCount = dest.getDestinationStatistics().getExpired().getCount(); |
290 | 294 |
|
291 | | - assertEquals( |
292 | | - "With ExpiryCheckEnabled=false, the expiry scan must not run — expired counter must be 0", |
293 | | - 0L, expiredCount); |
| 295 | + // The ExpiryCheckEnabled flag only skips the eager removeExpiredMessages() scan in |
| 296 | + // TopicSubscription.add(); it does NOT disable the always-on expiry paths (the per-message |
| 297 | + // isExpired() check when dispatching to the consumer, and client expired-acks), which may |
| 298 | + // still expire a small, timing-dependent number of messages. So the expired counter is not |
| 299 | + // reliably zero. The feature's actual guarantee is that the slow-consumer backlog is cleared |
| 300 | + // by the normal eviction strategy instead of the expiry scan — assert that eviction did the |
| 301 | + // work and dominates any incidental expiry. |
| 302 | + TopicSubscription sub = null; |
| 303 | + for (Subscription s : dest.getConsumers()) { |
| 304 | + if (s instanceof TopicSubscription) { |
| 305 | + sub = (TopicSubscription) s; |
| 306 | + break; |
| 307 | + } |
| 308 | + } |
| 309 | + assertNotNull("expected a TopicSubscription on the destination", sub); |
| 310 | + int evictedCount = sub.discarded(); |
| 311 | + |
| 312 | + assertTrue("eviction must clear the slow-consumer backlog when the eager expiry scan is " |
| 313 | + + "disabled (evicted=" + evictedCount + ")", evictedCount > 0); |
| 314 | + assertTrue("with the eager expiry scan disabled, eviction - not the expiry scan - must clear " |
| 315 | + + "the backlog (expired=" + expiredCount + ", evicted=" + evictedCount + ")", |
| 316 | + expiredCount < evictedCount); |
294 | 317 |
|
295 | 318 | conn.close(); |
296 | 319 | } finally { |
|
0 commit comments