Avoid race condition in LocalBitcoinNodeTests

Previously, Travis CI was failing non-deterministically due to a race
condition in which a thread was started in order to call the blocking
ServerSocket.accept() method, and sometimes the subsequent attempt by
LocalBitcoinNode.detectAndRun() to connect to that socket's port would
occur before the thread had actually called the accept() method.

This commit simplifies the approach by removing the thread entirely. As
it turns out, calling accept() is not necessary; simply constructing a
new ServerSocket() binds to and listens on the given port, such that a
subsequent attempt to connect() will succeed.
This commit is contained in:
Chris Beams 2020-01-10 23:31:27 +01:00
parent 37b669c710
commit efba975813
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73

View file

@ -3,7 +3,6 @@ package bisq.core.btc.nodes;
import java.net.ServerSocket;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.concurrent.atomic.AtomicBoolean;
@ -17,37 +16,28 @@ public class LocalBitcoinNodeTests {
private AtomicBoolean called = new AtomicBoolean(false);
private Runnable callback = () -> called.set(true);
private int port;
private ServerSocket socket;
private LocalBitcoinNode localBitcoinNode;
@Before
public void setUp() throws IOException {
// Find an available port
try (ServerSocket socket = new ServerSocket(0)) {
port = socket.getLocalPort();
}
localBitcoinNode = new LocalBitcoinNode(port);
// Bind to and listen on an available port
socket = new ServerSocket(0);
localBitcoinNode = new LocalBitcoinNode(socket.getLocalPort());
}
@Test
public void whenLocalBitcoinNodeIsDetected_thenCallbackGetsRun_andIsDetectedReturnsTrue() {
// Listen on the port, indicating that the local bitcoin node is running
new Thread(() -> {
try (ServerSocket socket = new ServerSocket(port)){
socket.accept();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}).start();
// Continue listening on the port, indicating the local Bitcoin node is running
localBitcoinNode.detectAndRun(callback);
assertTrue(called.get());
assertTrue(localBitcoinNode.isDetected());
}
@Test
public void whenLocalBitcoinNodeIsNotDetected_thenCallbackGetsRun_andIsDetectedReturnsFalse() {
// Leave port unbound, indicating that no local Bitcoin node is running
public void whenLocalBitcoinNodeIsNotDetected_thenCallbackGetsRun_andIsDetectedReturnsFalse() throws IOException {
// Stop listening on the port, indicating the local Bitcoin node is not running
socket.close();
localBitcoinNode.detectAndRun(callback);
assertTrue(called.get());
assertFalse(localBitcoinNode.isDetected());