This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-13249
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-event.git

commit 3bbe8a5c2606fc93cf1bfeb838a82b1acf517670
Author: Joerg Hoh <[email protected]>
AuthorDate: Tue Jun 23 20:06:32 2026 +0200

    SLING-13249 fix two synchronization bugs in OrderedQueueIT
    
    - Record the ordering-invariant violation and assert it on the test thread;
      an AssertionError thrown in the consumer (worker thread) was swallowed by
      the job framework and never failed the test.
    - Gate the completion wait on the queue/global statistics, not just the
      JOB_FINISHED notification count, so the statistics assertions no longer
      read stale values.
---
 .../org/apache/sling/event/it/OrderedQueueIT.java  | 33 +++++++++++++++++-----
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/test/java/org/apache/sling/event/it/OrderedQueueIT.java 
b/src/test/java/org/apache/sling/event/it/OrderedQueueIT.java
index 2039660..ea4fa8d 100644
--- a/src/test/java/org/apache/sling/event/it/OrderedQueueIT.java
+++ b/src/test/java/org/apache/sling/event/it/OrderedQueueIT.java
@@ -21,6 +21,7 @@ package org.apache.sling.event.it;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.sling.event.impl.Barrier;
 import org.apache.sling.event.impl.jobs.config.ConfigurationConstants;
@@ -41,9 +42,9 @@ import org.osgi.service.event.Event;
 import org.osgi.service.event.EventHandler;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.ops4j.pax.exam.CoreOptions.options;
 import static 
org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
 
@@ -80,6 +81,10 @@ public class OrderedQueueIT extends AbstractJobHandlingIT {
         final Barrier cb = new Barrier(2);
         final AtomicInteger count = new AtomicInteger(0);
         final AtomicInteger parallelCount = new AtomicInteger(0);
+        // The ordering invariant is checked on the queue worker thread, but 
assertions thrown there
+        // would be swallowed by the job framework (treated as a job failure) 
instead of failing the
+        // test. Record the first violation here and assert it on the test 
thread after processing.
+        final AtomicReference<String> orderingViolation = new 
AtomicReference<>();
         this.registerJobConsumer("sling/orderedtest/*", new JobConsumer() {
 
             private volatile int lastCounter = -1;
@@ -87,10 +92,12 @@ public class OrderedQueueIT extends AbstractJobHandlingIT {
             @Override
             public JobResult process(final Job job) {
                 final int counter = job.getProperty("counter", -10);
-                assertNotEquals("Counter property is missing", -10, counter);
-                assertTrue(
-                        "Counter should only increment by max of 1 " + counter 
+ " - " + lastCounter,
-                        counter == lastCounter || counter == lastCounter + 1);
+                if (counter == -10) {
+                    orderingViolation.compareAndSet(null, "Counter property is 
missing");
+                } else if (!(counter == lastCounter || counter == lastCounter 
+ 1)) {
+                    orderingViolation.compareAndSet(
+                            null, "Counter should only increment by max of 1: 
" + counter + " - " + lastCounter);
+                }
                 lastCounter = counter;
                 if ("sling/orderedtest/start".equals(job.getTopic())) {
                     cb.block();
@@ -150,13 +157,25 @@ public class OrderedQueueIT extends AbstractJobHandlingIT 
{
         }
         // start the queue
         q.resume();
-        while (count.get() < NUM_JOBS + 1) {
+        // Wait until the JOB_FINISHED notifications AND the queue/global 
statistics have all caught
+        // up. The statistics are updated on a different code path than the 
notification, so gating
+        // only on the notification count would let the assertions below read 
stale statistics.
+        while (count.get() < NUM_JOBS + 1
+                || q.getStatistics().getNumberOfFinishedJobs() < NUM_JOBS + 1
+                || jobManager.getStatistics().getNumberOfFinishedJobs() < 
NUM_JOBS + 1) {
             try {
-                Thread.sleep(500);
+                Thread.sleep(100);
             } catch (InterruptedException ie) {
                 // ignore
             }
         }
+
+        // fail the test on the test thread if the consumer observed an 
ordering violation
+        final String violation = orderingViolation.get();
+        if (violation != null) {
+            fail(violation);
+        }
+
         // we started one event before the test, so add one
         assertEquals("Finished count", NUM_JOBS + 1, count.get());
         assertEquals("Finished count", NUM_JOBS + 1, 
jobManager.getStatistics().getNumberOfFinishedJobs());

Reply via email to