From f9cfe863209504940ce702d9d95513de687407c4 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Tue, 16 May 2017 09:56:14 +0200 Subject: [PATCH] Make RemoteClusterConnectionTests more robust against cancelable threads aborts Today we assert hart if failure listeners are invoked more than once. Yet, this can happen if we cancel the execution since the caller and the handler will get the exception on the cancelable threads and will notify the listener concurrently if timinig allows. This commit relaxes the assertion towards handling multiple invocations with `ExecutionCancelledException` Closes #24010 Closes #24179 Closes vagnerclementino/elasticsearch/#98 --- .../transport/RemoteClusterConnectionTests.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java b/core/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java index f7ab29c95c5..38e73c209ae 100644 --- a/core/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java +++ b/core/src/test/java/org/elasticsearch/transport/RemoteClusterConnectionTests.java @@ -498,7 +498,7 @@ public class RemoteClusterConnectionTests extends ESTestCase { barrier.await(); CountDownLatch latch = new CountDownLatch(numConnectionAttempts); for (int i = 0; i < numConnectionAttempts; i++) { - AtomicReference executed = new AtomicReference<>(); + AtomicReference executed = new AtomicReference<>(); ActionListener listener = ActionListener.wrap( x -> { if (executed.compareAndSet(null, new RuntimeException())) { @@ -508,10 +508,21 @@ public class RemoteClusterConnectionTests extends ESTestCase { } }, x -> { - if (executed.compareAndSet(null, new RuntimeException())) { + if (executed.compareAndSet(null, x)) { latch.countDown(); } else { - throw new AssertionError("shit's been called twice", executed.get()); + final String message = x.getMessage(); + if ((executed.get().getClass() == x.getClass() + && "operation was cancelled reason [connect handler is closed]".equals(message) + && message.equals(executed.get().getMessage())) == false) { + // we do cancel the operation and that means that if timing allows it, the caller + // of a blocking call as well as the handler will get the exception from the + // ExecutionCancelledException concurrently. unless that is the case we fail + // if we get called more than once! + AssertionError assertionError = new AssertionError("shit's been called twice", x); + assertionError.addSuppressed(executed.get()); + throw assertionError; + } } if (x instanceof RejectedExecutionException || x instanceof AlreadyClosedException || x instanceof CancellableThreads.ExecutionCancelledException) {