use of com.radixdlt.network.p2p.transport.PeerChannel in project radixdlt by radixdlt.
the class MockP2PNetwork method createChannel.
void createChannel(int clientPeerIndex, RadixNodeUri serverPeerUri) {
final var clientPeer = nodes.get(clientPeerIndex);
final var serverPeerOpt = nodes.stream().filter(p -> p.uri.getHost().equals(serverPeerUri.getHost()) && p.uri.getPort() == serverPeerUri.getPort()).findAny();
final var clientSocketChannel = mock(SocketChannel.class);
final var clientChannel = new PeerChannel(clientPeer.injector.getInstance(P2PConfig.class), Addressing.ofNetwork(Network.LOCALNET), 1, "fork1", clientPeer.injector.getInstance(SystemCounters.class), clientPeer.injector.getInstance(Serialization.class), new SecureRandom(), ECKeyOps.fromKeyPair(clientPeer.keyPair), clientPeer.injector.getInstance(new Key<EventDispatcher<PeerEvent>>() {
}), Optional.of(serverPeerUri), clientSocketChannel, Optional.empty());
if (serverPeerOpt.isEmpty()) {
clientChannel.channelActive(null);
clientChannel.channelInactive(null);
return;
}
final var serverPeer = serverPeerOpt.get();
final var serverSocketChannel = mock(SocketChannel.class);
final var serverChannel = new PeerChannel(serverPeer.injector.getInstance(P2PConfig.class), Addressing.ofNetwork(Network.LOCALNET), 1, "fork1", serverPeer.injector.getInstance(SystemCounters.class), serverPeer.injector.getInstance(Serialization.class), new SecureRandom(), ECKeyOps.fromKeyPair(serverPeer.keyPair), serverPeer.injector.getInstance(new Key<EventDispatcher<PeerEvent>>() {
}), Optional.empty(), serverSocketChannel, Optional.empty());
when(clientSocketChannel.writeAndFlush(any())).thenAnswer(inv -> {
final var rawData = inv.getArgument(0);
serverChannel.channelRead0(null, (ByteBuf) rawData);
return null;
});
when(serverSocketChannel.writeAndFlush(any())).thenAnswer(inv -> {
final var rawData = inv.getArgument(0);
clientChannel.channelRead0(null, (ByteBuf) rawData);
return null;
});
when(clientSocketChannel.close()).thenAnswer(inv -> {
final var mockChannel = mock(ChannelHandlerContext.class);
when(mockChannel.channel()).thenReturn(mock(Channel.class));
clientChannel.channelInactive(mockChannel);
serverChannel.channelInactive(mockChannel);
return null;
});
when(serverSocketChannel.close()).thenAnswer(inv -> {
final var mockChannel = mock(ChannelHandlerContext.class);
when(mockChannel.channel()).thenReturn(mock(Channel.class));
serverChannel.channelInactive(mockChannel);
clientChannel.channelInactive(mockChannel);
return null;
});
serverChannel.channelActive(null);
clientChannel.channelActive(null);
}
use of com.radixdlt.network.p2p.transport.PeerChannel in project radixdlt by radixdlt.
the class PendingOutboundChannelsManagerTest method pending_outbound_channels_manager_should_return_the_same_future_when_called_from_diff_threads.
/*
* Tests whether the PendingOutboundChannelsManager can be safely accessed from multiple threads by
* calling `connectTo` from two threads and ensuring that only a single outbound connection
* request was triggered, and a single CompletableFuture object was returned to both callers.
*/
@Test
public void pending_outbound_channels_manager_should_return_the_same_future_when_called_from_diff_threads() throws Exception {
final var executorService = Executors.newFixedThreadPool(2);
final var sut = new PendingOutboundChannelsManager(P2PConfig.fromRuntimeProperties(new RuntimeProperties(new JSONObject(), new String[] {})), mock(PeerOutboundBootstrap.class), rmock(ScheduledEventDispatcher.class), rmock(EventDispatcher.class));
final var remoteNodeId = NodeId.fromPublicKey(ECKeyPair.generateNew().getPublicKey());
final var remoteNodeUri = RadixNodeUri.fromPubKeyAndAddress(1, remoteNodeId.getPublicKey(), "127.0.0.1", 30000);
// in case of invalid concurrent access, but doesn't take too long in a happy scenario.
for (int i = 0; i < 200; i++) {
final var futureRef1 = new AtomicReference<CompletableFuture<PeerChannel>>();
final var futureRef2 = new AtomicReference<CompletableFuture<PeerChannel>>();
executorService.invokeAll(List.of(Executors.callable(() -> futureRef1.set(sut.connectTo(remoteNodeUri))), Executors.callable(() -> futureRef2.set(sut.connectTo(remoteNodeUri)))));
assertNotNull(futureRef1.get());
assertNotNull(futureRef2.get());
// Assert the exact same future object is returned
assertSame(futureRef1.get(), futureRef2.get());
// Callback to PendingOutboundChannelsManager with successful connection so that it clears
// pendingChannels
final var peerChannel = mock(PeerChannel.class);
when(peerChannel.getRemoteNodeId()).thenReturn(remoteNodeId);
sut.peerEventProcessor().process(new PeerEvent.PeerConnected(peerChannel));
// Just to make sure the Futures were completed
assertTrue(futureRef1.get().isDone());
assertTrue(futureRef2.get().isDone());
}
}
Aggregations