Skip to content

Commit a8941a9

Browse files
jasontedorjimczi
authored andcommitted
Fix race condition in scheduler engine test
This commit addresses a race condition in the scheduler engine test that a listener that throws an exception does not cause other listeners to be skipped. The race here is that we were counting down a latch, and then throwing an exception yet an assertion that expected the exception to have been thrown already could execute after the latch was counted down for the final time but before the exception was thrown and acted upon by the scheduler engine. This commit addresses this by moving the counting down of the latch to definitely be after the exception was acted upon by the scheduler engine.
1 parent 77282e8 commit a8941a9

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/scheduler/SchedulerEngineTests.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,19 @@
2121
import java.util.concurrent.atomic.AtomicBoolean;
2222
import java.util.concurrent.atomic.AtomicInteger;
2323

24+
import static org.hamcrest.Matchers.any;
2425
import static org.hamcrest.Matchers.arrayWithSize;
2526
import static org.hamcrest.Matchers.equalTo;
2627
import static org.hamcrest.Matchers.instanceOf;
28+
import static org.mockito.Matchers.argThat;
29+
import static org.mockito.Mockito.doAnswer;
2730
import static org.mockito.Mockito.mock;
2831
import static org.mockito.Mockito.times;
2932
import static org.mockito.Mockito.verify;
3033
import static org.mockito.Mockito.verifyNoMoreInteractions;
3134

3235
public class SchedulerEngineTests extends ESTestCase {
3336

34-
@AwaitsFix(bugUrl="https://github.com/elastic/elasticsearch/issues/33124")
3537
public void testListenersThrowingExceptionsDoNotCauseOtherListenersToBeSkipped() throws InterruptedException {
3638
final Logger mockLogger = mock(Logger.class);
3739
final SchedulerEngine engine = new SchedulerEngine(Settings.EMPTY, Clock.systemUTC(), mockLogger);
@@ -40,6 +42,7 @@ public void testListenersThrowingExceptionsDoNotCauseOtherListenersToBeSkipped()
4042
final int numberOfListeners = randomIntBetween(1, 32);
4143
int numberOfFailingListeners = 0;
4244
final CountDownLatch latch = new CountDownLatch(numberOfListeners);
45+
4346
for (int i = 0; i < numberOfListeners; i++) {
4447
final AtomicBoolean trigger = new AtomicBoolean();
4548
final SchedulerEngine.Listener listener;
@@ -55,12 +58,17 @@ public void testListenersThrowingExceptionsDoNotCauseOtherListenersToBeSkipped()
5558
numberOfFailingListeners++;
5659
listener = event -> {
5760
if (trigger.compareAndSet(false, true)) {
58-
latch.countDown();
61+
// we count down the latch after this exception is caught and mock logged in SchedulerEngine#notifyListeners
5962
throw new RuntimeException(getTestName());
6063
} else {
6164
fail("listener invoked twice");
6265
}
6366
};
67+
doAnswer(invocationOnMock -> {
68+
// this happens after the listener has been notified, threw an exception, and then mock logged the exception
69+
latch.countDown();
70+
return null;
71+
}).when(mockLogger).warn(argThat(any(ParameterizedMessage.class)), argThat(any(RuntimeException.class)));
6472
}
6573
listeners.add(Tuple.tuple(listener, trigger));
6674
}
@@ -135,7 +143,7 @@ public void testListenersThrowingExceptionsDoNotCauseNextScheduledTaskToBeSkippe
135143
listenersLatch.await();
136144
assertTrue(listeners.stream().map(Tuple::v2).allMatch(count -> count.get() == numberOfSchedules));
137145
latch.await();
138-
assertFailedListenerLogMessage(mockLogger, numberOfListeners * numberOfSchedules);
146+
assertFailedListenerLogMessage(mockLogger, numberOfSchedules * numberOfListeners);
139147
verifyNoMoreInteractions(mockLogger);
140148
} finally {
141149
engine.stop();

0 commit comments

Comments
 (0)