33using System . Collections . Generic ;
44using System . Linq ;
55using System . Net ;
6+ using System . Threading ;
67using System . Threading . Tasks ;
78using Libplanet . Crypto ;
89using Libplanet . Net . Messages ;
1819
1920namespace Libplanet . Net . Tests . Transports
2021{
22+ [ CollectionDefinition ( nameof ( Libp2pTransportTest ) , DisableParallelization = true ) ]
2123 public class Libp2pTransportTest : IDisposable
2224 {
25+ public const int Timeout = 30_000 ;
2326 private bool _disposed ;
2427 private ILogger _logger ;
2528
@@ -41,7 +44,7 @@ public Libp2pTransportTest(ITestOutputHelper testOutputHelper)
4144 Dispose ( false ) ;
4245 }
4346
44- [ Fact ( Timeout = 10_000 ) ]
47+ [ Fact ( Timeout = Timeout ) ]
4548 public async Task Initialize ( )
4649 {
4750 PrivateKey privateKey = new PrivateKey ( ) ;
@@ -67,10 +70,16 @@ public async Task Initialize()
6770 Assert . Equal ( expected , transport . AsPeer ) ;
6871 }
6972
70- [ Fact ( Timeout = 10_000 ) ]
71- public async Task DialToListeners ( )
73+ [ Theory ( Timeout = Timeout ) ]
74+ [ InlineData ( true ) ]
75+ [ InlineData ( false ) ]
76+ public async Task DialToListeners ( bool usePortZero )
7277 {
78+ // NOTE: Using port 0 does not work for this test.
7379 int count = 2 ;
80+ List < int > freePorts = usePortZero
81+ ? Enumerable . Range ( 0 , count ) . Select ( _ => 0 ) . ToList ( )
82+ : TestUtils . GetFreePorts ( count ) ;
7483 List < PrivateKey > privateKeys = Enumerable
7584 . Range ( 0 , count )
7685 . Select ( _ => new PrivateKey ( ) )
@@ -80,7 +89,7 @@ public async Task DialToListeners()
8089 . Select ( i => new Libp2pTransport (
8190 privateKeys [ i ] ,
8291 new AppProtocolVersionOptions ( ) ,
83- new HostOptions ( "127.0.0.1" , new IceServer [ ] { } , 0 ) ) )
92+ new HostOptions ( "127.0.0.1" , new IceServer [ ] { } , freePorts [ i ] ) ) )
8493 . ToList ( ) ;
8594 List < IServiceProvider > serviceProviders = transports
8695 . Select ( transport => GetServiceProvider ( transport ) )
@@ -92,11 +101,12 @@ public async Task DialToListeners()
92101 . Range ( 0 , count )
93102 . Select ( i => peerFactories [ i ] . Create (
94103 CryptoKeyConverter . ToLibp2pIdentity ( privateKeys [ i ] ) ,
95- "/ip4/127.0.0.1/tcp/0 " ) )
104+ $ "/ip4/127.0.0.1/tcp/{ freePorts [ i ] } ") )
96105 . ToList ( ) ;
97- List < IListener > listeners = localPeers
98- . Select ( async localPeer =>
99- await localPeer . ListenAsync ( "/ip4/127.0.0.1/tcp/0" , default ) )
106+ List < IListener > listeners = Enumerable
107+ . Range ( 0 , count )
108+ . Select ( async i =>
109+ await localPeers [ i ] . ListenAsync ( $ "/ip4/127.0.0.1/tcp/{ freePorts [ i ] } ", default ) )
100110 . Select ( task => task . Result )
101111 . ToList ( ) ;
102112 List < Multiaddress > listenerAddresses = listeners
@@ -110,15 +120,37 @@ await localPeer.ListenAsync("/ip4/127.0.0.1/tcp/0", default))
110120 Assert . Equal ( listenerAddresses [ 0 ] , remote1 . Address ) ;
111121 }
112122
113- [ Fact ( Timeout = 10_000 ) ]
114- public async Task DialToTransports ( )
123+ [ Fact ( Timeout = Timeout ) ]
124+ public async Task DialCancel ( )
125+ {
126+ PrivateKey privateKey = new PrivateKey ( ) ;
127+ List < int > freePorts = TestUtils . GetFreePorts ( 2 ) ;
128+ Libp2pTransport transport = await Libp2pTransport . Create (
129+ privateKey ,
130+ new AppProtocolVersionOptions ( ) ,
131+ new HostOptions ( "127.0.0.1" , new IceServer [ ] { } , freePorts [ 0 ] ) ) ;
132+
133+ Identity identity = CryptoKeyConverter . ToLibp2pIdentity ( new PrivateKey ( ) ) ;
134+ Multiaddress badAddress = $ "/ip4/127.0.0.1/tcp/{ freePorts [ 1 ] } /p2p/{ identity . PeerId } ";
135+ CancellationTokenSource cts = new CancellationTokenSource ( ) ;
136+ cts . CancelAfter ( 1_000 ) ;
137+ await Assert . ThrowsAsync < TaskCanceledException > (
138+ async ( ) => await transport . LocalPeer . DialAsync ( badAddress , cts . Token ) ) ;
139+ }
140+
141+ [ Theory ( Timeout = Timeout ) ]
142+ [ InlineData ( true ) ]
143+ [ InlineData ( false ) ]
144+ public async Task DialToTransports ( bool usePortZero )
115145 {
116146 int count = 2 ;
147+ List < int > freePorts = usePortZero
148+ ? Enumerable . Range ( 0 , count ) . Select ( _ => 0 ) . ToList ( )
149+ : TestUtils . GetFreePorts ( count ) ;
117150 List < PrivateKey > privateKeys = Enumerable
118151 . Range ( 0 , count )
119152 . Select ( _ => new PrivateKey ( ) )
120153 . ToList ( ) ;
121- List < int > freePorts = TestUtils . GetFreePorts ( 2 ) ;
122154 List < HostOptions > hosts = freePorts
123155 . Select ( freePort => new HostOptions ( "127.0.0.1" , new IceServer [ ] { } , freePort ) )
124156 . ToList ( ) ;
@@ -140,15 +172,19 @@ public async Task DialToTransports()
140172 Assert . Equal ( transports [ 0 ] . ListenerAddress , remote1 . Address ) ;
141173 }
142174
143- [ Fact ( Timeout = 10_000 ) ]
144- public async Task RequestReply ( )
175+ [ Theory ( Timeout = Timeout ) ]
176+ [ InlineData ( true ) ]
177+ [ InlineData ( false ) ]
178+ public async Task RequestReply ( bool usePortZero )
145179 {
146180 int count = 2 ;
181+ List < int > freePorts = usePortZero
182+ ? Enumerable . Range ( 0 , count ) . Select ( _ => 0 ) . ToList ( )
183+ : TestUtils . GetFreePorts ( count ) ;
147184 List < PrivateKey > privateKeys = Enumerable
148185 . Range ( 0 , count )
149186 . Select ( _ => new PrivateKey ( ) )
150187 . ToList ( ) ;
151- List < int > freePorts = TestUtils . GetFreePorts ( 2 ) ;
152188 List < Libp2pTransport > transports = Enumerable
153189 . Range ( 0 , count )
154190 . Select ( async i => await Libp2pTransport . Create (
@@ -166,15 +202,54 @@ public async Task RequestReply()
166202 }
167203 } ) ;
168204
169- List < Message > reply = ( await transports [ 0 ] . SendMessageAsync (
205+ Message reply = await transports [ 0 ] . SendMessageAsync (
170206 transports [ 1 ] . AsPeer ,
171207 new PingMsg ( ) ,
172208 TimeSpan . FromSeconds ( 5 ) ,
173- 1 ,
174- true ,
175- default ) ) . ToList ( ) ;
176- Message single = Assert . Single < Message > ( reply ) ;
177- Assert . IsType < PongMsg > ( single . Content ) ;
209+ default ) ;
210+ Assert . IsType < PongMsg > ( reply . Content ) ;
211+ }
212+
213+ [ Theory ( Timeout = Timeout ) ]
214+ [ InlineData ( true ) ]
215+ [ InlineData ( false ) ]
216+ public async Task Broadcast ( bool usePortZero )
217+ {
218+ int count = 4 ;
219+ List < int > freePorts = usePortZero
220+ ? Enumerable . Range ( 0 , count ) . Select ( _ => 0 ) . ToList ( )
221+ : TestUtils . GetFreePorts ( count ) ;
222+ List < PrivateKey > privateKeys = Enumerable
223+ . Range ( 0 , count )
224+ . Select ( _ => new PrivateKey ( ) )
225+ . ToList ( ) ;
226+ List < Libp2pTransport > transports = Enumerable
227+ . Range ( 0 , count )
228+ . Select ( async i => await Libp2pTransport . Create (
229+ privateKeys [ i ] ,
230+ new AppProtocolVersionOptions ( ) ,
231+ new HostOptions ( "127.0.0.1" , new IceServer [ ] { } , freePorts [ i ] ) ) )
232+ . Select ( task => task . Result )
233+ . ToList ( ) ;
234+
235+ int receivedCount = 0 ;
236+ foreach ( var transport in transports . Skip ( 1 ) . ToList ( ) )
237+ {
238+ transport . ProcessMessageHandler . Register ( async ( message , channel ) =>
239+ {
240+ if ( message . Content is PingMsg )
241+ {
242+ await channel . Writer . WriteAsync ( new PongMsg ( ) ) ;
243+ receivedCount ++ ;
244+ }
245+ } ) ;
246+ }
247+
248+ transports [ 0 ] . BroadcastMessage (
249+ transports . Skip ( 1 ) . Select ( transport => transport . AsPeer ) . ToList ( ) ,
250+ new PingMsg ( ) ) ;
251+ await Task . Delay ( 1_000 ) ;
252+ Assert . Equal ( count - 1 , receivedCount ) ;
178253 }
179254
180255 public void Dispose ( )
0 commit comments