zombienet_orchestrator/generators/
port.rs1use std::net::{SocketAddr, TcpListener};
2
3use configuration::shared::types::Port;
4use socket2::{Domain, Protocol, Socket, Type};
5use support::constants::THIS_IS_A_BUG;
6
7use super::errors::GeneratorError;
8use crate::shared::types::ParkedPort;
9
10enum PortTypes {
12 Rpc,
13 P2P,
14 Prometheus,
15}
16
17pub fn generate(port: Option<Port>) -> Result<ParkedPort, GeneratorError> {
18 let port = port.unwrap_or(0);
19 let addr: SocketAddr = format!("[::]:{port}")
20 .parse()
21 .expect("addr should be valid");
22 let socket = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP))
23 .map_err(|_e| GeneratorError::PortGeneration(port, "Can't create the socket".into()))?;
24
25 socket.set_only_v6(false).map_err(|_e| {
27 GeneratorError::PortGeneration(port, "Can't set v6 only to false in socket".into())
28 })?;
29 socket
30 .bind(&addr.into())
31 .map_err(|_e| GeneratorError::PortGeneration(port, "Can't bind in socket".into()))?;
32 socket
33 .listen(128)
34 .map_err(|_e| GeneratorError::PortGeneration(port, "Can't listen in socket".into()))?;
35
36 let listener: TcpListener = socket.into();
37 let port = listener
38 .local_addr()
39 .expect(&format!(
40 "We should always get the local_addr from the listener {THIS_IS_A_BUG}"
41 ))
42 .port();
43 Ok(ParkedPort::new(port, listener))
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 #[test]
50 fn generate_random() {
51 let port = generate(None).unwrap();
52 let listener = port.1.write().unwrap();
53
54 assert!(listener.is_some());
55 }
56
57 #[test]
58 fn generate_fixed_port() {
59 let port = generate(Some(33056)).unwrap();
60 let listener = port.1.write().unwrap();
61
62 assert!(listener.is_some());
63 assert_eq!(port.0, 33056);
64 }
65}