11/// Integration tests for UDP tracker server
22///
33/// cargo test udp_tracker_server -- --nocapture
4-
5- #[ macro_use]
6- extern crate lazy_static;
7-
84extern crate rand;
95
106mod udp_tracker_server {
11-
127 use core:: panic;
138 use std:: io:: Cursor ;
14- use std:: net:: IpAddr ;
9+ use std:: net:: Ipv4Addr ;
1510 use std:: sync:: atomic:: { AtomicBool , Ordering } ;
1611 use std:: sync:: Arc ;
17- use std:: sync:: RwLock ;
1812
1913 use rand:: { thread_rng, Rng } ;
2014
@@ -34,26 +28,23 @@ mod udp_tracker_server {
3428
3529 fn tracker_configuration ( ) -> Arc < Configuration > {
3630 let mut config = Configuration :: default ( ) ;
37- //config.log_level = Some("debug".to_owned()); // Uncomment to enable logging
38- config. external_ip = Some ( "127.0.0.1" . to_owned ( ) ) ;
39- config. udp_trackers [ 0 ] . bind_address = "127.0.0.1:6969" . to_owned ( ) ;
31+ config. log_level = Some ( "off" . to_owned ( ) ) ; // "off" is necessary when running multiple trackers
32+ config. udp_trackers [ 0 ] . bind_address = format ! ( "127.0.0.1:{}" , ephemeral_random_port( ) ) ;
4033 Arc :: new ( config)
4134 }
4235
43- fn tracker_bind_address ( ) -> String {
44- tracker_configuration ( ) . udp_trackers [ 0 ] . bind_address . clone ( )
45- }
46-
4736 pub struct UdpServer {
4837 pub started : AtomicBool ,
4938 pub job : Option < JoinHandle < ( ) > > ,
39+ pub bind_address : Option < String > ,
5040 }
5141
5242 impl UdpServer {
5343 pub fn new ( ) -> Self {
5444 Self {
5545 started : AtomicBool :: new ( false ) ,
5646 job : None ,
47+ bind_address : None ,
5748 }
5849 }
5950
@@ -76,20 +67,22 @@ mod udp_tracker_server {
7667 // Initialize logging
7768 logging:: setup_logging ( & configuration) ;
7869
70+ let udp_tracker_config = & configuration. udp_trackers [ 0 ] ;
71+
7972 // Start the UDP tracker job
80- self . job = Some ( udp_tracker:: start_job ( & configuration. udp_trackers [ 0 ] , tracker. clone ( ) ) ) ;
73+ self . job = Some ( udp_tracker:: start_job ( & udp_tracker_config, tracker. clone ( ) ) ) ;
74+
75+ self . bind_address = Some ( udp_tracker_config. bind_address . clone ( ) ) ;
8176
8277 self . started . store ( true , Ordering :: Relaxed ) ;
8378 }
8479 }
8580 }
8681
87- lazy_static ! {
88- static ref SERVER : RwLock <UdpServer > = RwLock :: new( UdpServer :: new( ) ) ;
89- }
90-
91- async fn start_udp_server ( configuration : Arc < Configuration > ) {
92- SERVER . write ( ) . unwrap ( ) . start ( configuration. clone ( ) ) . await ;
82+ async fn new_running_udp_server ( configuration : Arc < Configuration > ) -> UdpServer {
83+ let mut udp_server = UdpServer :: new ( ) ;
84+ udp_server. start ( configuration) . await ;
85+ udp_server
9386 }
9487
9588 struct UdpClient {
@@ -207,43 +200,49 @@ mod udp_tracker_server {
207200 } ;
208201 }
209202
210- // #[tokio::test]
211- // async fn should_return_a_bad_request_response_when_the_client_sends_an_empty_request() {
212- // start_udp_server( tracker_configuration().clone()).await ;
203+ #[ tokio:: test]
204+ async fn should_return_a_bad_request_response_when_the_client_sends_an_empty_request ( ) {
205+ let configuration = tracker_configuration ( ) ;
213206
214- // let client = new_connected_udp_client(&tracker_bind_address() ).await;
207+ let udp_server = new_running_udp_server ( configuration ) . await ;
215208
216- // client.send(&empty_udp_request ()).await;
209+ let client = new_connected_udp_client ( & udp_server . bind_address . unwrap ( ) ) . await ;
217210
218- // let mut buffer = empty_buffer();
219- // client.receive(&mut buffer).await;
220- // let response = Response::from_bytes(&buffer, true).unwrap();
211+ client. send ( & empty_udp_request ( ) ) . await ;
221212
222- // assert!(is_error_response(&response, "bad request"));
223- // }
213+ let mut buffer = empty_buffer ( ) ;
214+ client. receive ( & mut buffer) . await ;
215+ let response = Response :: from_bytes ( & buffer, true ) . unwrap ( ) ;
224216
225- // #[tokio::test]
226- // async fn should_return_a_connect_response_when_the_client_sends_a_connection_request() {
227- // start_udp_server(tracker_configuration().clone()).await;
217+ assert ! ( is_error_response( & response, "bad request" ) ) ;
218+ }
228219
229- // let client = new_connected_udp_tracker_client(&tracker_bind_address()).await;
220+ #[ tokio:: test]
221+ async fn should_return_a_connect_response_when_the_client_sends_a_connection_request ( ) {
222+ let configuration = tracker_configuration ( ) ;
230223
231- // let connect_request = ConnectRequest {
232- // transaction_id: TransactionId(123),
233- // };
224+ let udp_server = new_running_udp_server ( configuration) . await ;
234225
235- // client.send(connect_request.into ()).await;
226+ let client = new_connected_udp_tracker_client ( & udp_server . bind_address . unwrap ( ) ) . await ;
236227
237- // let response = client.receive().await;
228+ let connect_request = ConnectRequest {
229+ transaction_id : TransactionId ( 123 ) ,
230+ } ;
238231
239- // assert!(is_connect_response(&response, TransactionId(123)));
240- // }
232+ client. send ( connect_request. into ( ) ) . await ;
233+
234+ let response = client. receive ( ) . await ;
235+
236+ assert ! ( is_connect_response( & response, TransactionId ( 123 ) ) ) ;
237+ }
241238
242239 #[ tokio:: test]
243240 async fn should_return_an_announce_response_when_the_client_sends_an_announce_request ( ) {
244- start_udp_server ( tracker_configuration ( ) . clone ( ) ) . await ;
241+ let configuration = tracker_configuration ( ) ;
242+
243+ let udp_server = new_running_udp_server ( configuration) . await ;
245244
246- let client = new_connected_udp_tracker_client ( & tracker_bind_address ( ) ) . await ;
245+ let client = new_connected_udp_tracker_client ( & udp_server . bind_address . unwrap ( ) ) . await ;
247246
248247 // todo: extract client.connect() -> ConnectionId
249248
@@ -264,21 +263,16 @@ mod udp_tracker_server {
264263
265264 // Send announce request
266265
267- let client_ip = match client. udp_client . socket . local_addr ( ) . unwrap ( ) . ip ( ) {
268- IpAddr :: V4 ( ip4) => ip4,
269- _ => panic ! ( "error: IPV6 addresses cannot be used for the client ip in the announce request. Try to use IPV4." ) ,
270- } ;
271-
272266 let announce_request = AnnounceRequest {
273- connection_id : ConnectionId ( 8724592475294857 ) ,
267+ connection_id : ConnectionId ( connection_id . 0 ) ,
274268 transaction_id : TransactionId ( 123i32 ) ,
275269 info_hash : InfoHash ( [ 0u8 ; 20 ] ) ,
276270 peer_id : PeerId ( [ 255u8 ; 20 ] ) ,
277271 bytes_downloaded : NumberOfBytes ( 0i64 ) ,
278272 bytes_uploaded : NumberOfBytes ( 0i64 ) ,
279273 bytes_left : NumberOfBytes ( 0i64 ) ,
280274 event : AnnounceEvent :: Started ,
281- ip_address : Some ( client_ip ) ,
275+ ip_address : Some ( Ipv4Addr :: new ( 0 , 0 , 0 , 0 ) ) ,
282276 key : PeerKey ( 0u32 ) ,
283277 peers_wanted : NumberOfPeers ( 1i32 ) ,
284278 port : Port ( client. udp_client . socket . local_addr ( ) . unwrap ( ) . port ( ) ) ,
0 commit comments