From e4c196cd1a2c79bd368db4bc8161a2ab7968789b Mon Sep 17 00:00:00 2001 From: Jeremy Dahlgren Date: Fri, 13 Jun 2025 12:06:14 -0400 Subject: [PATCH] Fix RestCancellableNodeClientTests.testConcurrentExecuteAndClose() (#129294) Fixes a race condition in testConcurrentExecuteAndClose() where awaitClose() is called before addCloseListener() has been called, resulting in a situation where closeListener is never completed and the closeLatch is never pulled. Closes #129121 --- .../rest/action/RestCancellableNodeClientTests.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java b/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java index 00aa44ac73acb..84e7a35e3d7b4 100644 --- a/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java +++ b/server/src/test/java/org/elasticsearch/rest/action/RestCancellableNodeClientTests.java @@ -303,6 +303,11 @@ public void addCloseListener(ActionListener listener) { // if the channel is already closed, the listener gets notified immediately, from the same thread. if (open.get() == false) { listener.onResponse(null); + // Ensure closeLatch is pulled by completing the closeListener with a noop that is ignored if it is already completed. + // Note that when the channel is closed we may see multiple addCloseListener() calls, so we do not assert on isDone() here, + // and since closeListener may already be completed we cannot rely on it to complete the current listener, so we first + // complete it directly and then pass a noop to closeListener. + closeListener.onResponse(ActionListener.assertOnce(ActionListener.noop())); } else { assertFalse("close listener already set, only one is allowed!", closeListener.isDone()); closeListener.onResponse(ActionListener.assertOnce(listener));