Fixes a race condition in HandshakeWaitingHandlerTests

Closes elastic/elasticsearch#1210

Original commit: elastic/x-pack-elasticsearch@bf130a969e
This commit is contained in:
Igor Motov 2015-12-30 10:54:22 -05:00
parent 2cec08798b
commit c4569432d1
1 changed files with 13 additions and 17 deletions

View File

@ -46,12 +46,13 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference;
import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
public class HandshakeWaitingHandlerTests extends ESTestCase { public class HandshakeWaitingHandlerTests extends ESTestCase {
private static final int CONCURRENT_CLIENT_REQUESTS = 20; private static final int CONCURRENT_CLIENT_REQUESTS = 20;
@ -63,8 +64,7 @@ public class HandshakeWaitingHandlerTests extends ESTestCase {
private ClientBootstrap clientBootstrap; private ClientBootstrap clientBootstrap;
private SSLContext sslContext; private SSLContext sslContext;
private final AtomicBoolean failed = new AtomicBoolean(false); private final AtomicReference<Throwable> failureCause = new AtomicReference<>();
private volatile Throwable failureCause = null;
private ExecutorService threadPoolExecutor; private ExecutorService threadPoolExecutor;
@Before @Before
@ -99,8 +99,7 @@ public class HandshakeWaitingHandlerTests extends ESTestCase {
serverBootstrap.shutdown(); serverBootstrap.shutdown();
serverBootstrap.releaseExternalResources(); serverBootstrap.releaseExternalResources();
failed.set(false); failureCause.set(null);
failureCause = null;
} }
public void testWriteBeforeHandshakeFailsWithoutHandler() throws Exception { public void testWriteBeforeHandshakeFailsWithoutHandler() throws Exception {
@ -127,13 +126,13 @@ public class HandshakeWaitingHandlerTests extends ESTestCase {
handshakeFuture.getChannel().close(); handshakeFuture.getChannel().close();
} }
if (failed.get()) { if (failureCause.get() != null) {
assertThat(failureCause, anyOf(instanceOf(SSLException.class), instanceOf(AssertionError.class))); assertThat(failureCause.get(), anyOf(instanceOf(SSLException.class), instanceOf(AssertionError.class)));
break; break;
} }
} }
assertThat("Expected this test to fail with an SSLException or AssertionError", failed.get(), is(true)); assertThat("Expected this test to fail with an SSLException or AssertionError", failureCause.get(), notNullValue());
} }
@AwaitsFix(bugUrl = "https://github.com/elasticsearch/elasticsearch-shield/issues/533") @AwaitsFix(bugUrl = "https://github.com/elasticsearch/elasticsearch-shield/issues/533")
@ -176,13 +175,12 @@ public class HandshakeWaitingHandlerTests extends ESTestCase {
} }
private void assertNotFailed() { private void assertNotFailed() {
if (failed.get()) { if (failureCause.get() != null) {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
if (failed.get()) { if (failureCause.get() != null) {
failureCause.printStackTrace(new PrintWriter(writer)); failureCause.get().printStackTrace(new PrintWriter(writer));
} }
assertThat("Expected this test to always pass with the HandshakeWaitingHandler in pipeline\n" + writer.toString(), failureCause.get(), nullValue());
assertThat("Expected this test to always pass with the HandshakeWaitingHandler in pipeline\n" + writer.toString(), failed.get(), is(false));
} }
} }
@ -226,9 +224,7 @@ public class HandshakeWaitingHandlerTests extends ESTestCase {
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
Throwable cause = e.getCause(); Throwable cause = e.getCause();
// Only save first cause // Only save first cause
if (failed.compareAndSet(false, true)) { failureCause.compareAndSet(null, cause);
failureCause = cause;
}
ctx.getChannel().close(); ctx.getChannel().close();
} }
}); });