1use std::{io, net, thread};
3
4use ntex_net::{tcp_connect, Io};
5use ntex_rt::System;
6use ntex_service::ServiceFactory;
7use socket2::{Domain, SockAddr, Socket, Type};
8
9use super::{Server, ServerBuilder};
10
11pub fn test_server<F, R>(factory: F) -> TestServer
43where
44 F: Fn() -> R + Send + Clone + 'static,
45 R: ServiceFactory<Io> + 'static,
46{
47 let (tx, rx) = oneshot::channel();
48 thread::spawn(move || {
50 let sys = System::new("ntex-test-server");
51 let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
52 let local_addr = tcp.local_addr().unwrap();
53 let system = sys.system();
54
55 sys.run(move || {
56 let server = ServerBuilder::new()
57 .listen("test", tcp, move |_| factory())?
58 .set_tag("test", "TEST-SERVER")
59 .workers(1)
60 .disable_signals()
61 .run();
62
63 ntex_rt::spawn(async move {
64 ntex_util::time::sleep(ntex_util::time::Millis(75)).await;
65 tx.send((system, local_addr, server))
66 .expect("Failed to send Server to TestServer");
67 });
68
69 Ok(())
70 })
71 });
72
73 let (system, addr, server) = rx.recv().unwrap();
74
75 TestServer {
76 addr,
77 server,
78 system,
79 }
80}
81
82pub fn build_test_server<F>(factory: F) -> TestServer
84where
85 F: FnOnce(ServerBuilder) -> ServerBuilder + Send + 'static,
86{
87 let (tx, rx) = oneshot::channel();
88 thread::spawn(move || {
90 let sys = System::new("ntex-test-server");
91 let system = sys.system();
92
93 sys.run(|| {
94 let server = factory(super::build()).workers(1).disable_signals().run();
95 tx.send((system, server))
96 .expect("Failed to send Server to TestServer");
97 Ok(())
98 })
99 });
100 let (system, server) = rx.recv().unwrap();
101
102 TestServer {
103 system,
104 server,
105 addr: "127.0.0.1:0".parse().unwrap(),
106 }
107}
108
109#[derive(Debug)]
110pub struct TestServer {
112 addr: net::SocketAddr,
113 system: System,
114 server: Server,
115}
116
117impl TestServer {
118 pub fn addr(&self) -> net::SocketAddr {
120 self.addr
121 }
122
123 pub fn set_addr(mut self, addr: net::SocketAddr) -> Self {
124 self.addr = addr;
125 self
126 }
127
128 pub async fn connect(&self) -> io::Result<Io> {
130 tcp_connect(self.addr).await
131 }
132
133 pub fn stop(&self) {
135 self.system.stop();
136 }
137
138 pub fn unused_addr() -> net::SocketAddr {
140 let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
141 let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap();
142 socket.set_reuse_address(true).unwrap();
143 socket.bind(&SockAddr::from(addr)).unwrap();
144 let tcp = net::TcpListener::from(socket);
145 tcp.local_addr().unwrap()
146 }
147
148 pub fn server(&self) -> Server {
150 self.server.clone()
151 }
152}
153
154impl Drop for TestServer {
155 fn drop(&mut self) {
156 self.stop()
157 }
158}