Skip to content

Commit 01d2f18

Browse files
authored
simplify test server (#431)
1 parent e92b5aa commit 01d2f18

File tree

9 files changed

+120
-116
lines changed

9 files changed

+120
-116
lines changed

actix-server/CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changes
22

33
## Unreleased - 2021-xx-xx
4+
- Simplify `TestServer`. [#431]
5+
6+
[#431]: https://github.com/actix/actix-net/pull/431
47

58

69
## 2.0.0-rc.1 - 2021-12-05

actix-server/src/builder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,11 @@ impl ServerBuilder {
140140
}
141141

142142
/// Add new service to the server.
143-
pub fn bind<F, U, N: AsRef<str>>(mut self, name: N, addr: U, factory: F) -> io::Result<Self>
143+
pub fn bind<F, U, N>(mut self, name: N, addr: U, factory: F) -> io::Result<Self>
144144
where
145145
F: ServerServiceFactory<TcpStream>,
146146
U: ToSocketAddrs,
147+
N: AsRef<str>,
147148
{
148149
let sockets = bind_addr(addr, self.backlog)?;
149150

actix-server/src/test_server.rs

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{Server, ServerBuilder, ServerHandle, ServerServiceFactory};
1616
///
1717
/// #[actix_rt::main]
1818
/// async fn main() {
19-
/// let srv = TestServer::with(|| fn_service(
19+
/// let srv = TestServer::start(|| fn_service(
2020
/// |sock| async move {
2121
/// println!("New connection: {:?}", sock);
2222
/// Ok::<_, ()>(())
@@ -28,8 +28,8 @@ use crate::{Server, ServerBuilder, ServerHandle, ServerServiceFactory};
2828
/// ```
2929
pub struct TestServer;
3030

31-
/// Test server runtime
32-
pub struct TestServerRuntime {
31+
/// Test server handle.
32+
pub struct TestServerHandle {
3333
addr: net::SocketAddr,
3434
host: String,
3535
port: u16,
@@ -38,46 +38,26 @@ pub struct TestServerRuntime {
3838
}
3939

4040
impl TestServer {
41-
/// Start new server with server builder.
42-
pub fn start<F>(mut factory: F) -> TestServerRuntime
43-
where
44-
F: FnMut(ServerBuilder) -> ServerBuilder + Send + 'static,
45-
{
46-
let (tx, rx) = mpsc::channel();
47-
48-
// run server in separate thread
49-
let thread_handle = thread::spawn(move || {
50-
System::new().block_on(async {
51-
let server = factory(Server::build()).workers(1).disable_signals().run();
52-
tx.send(server.handle()).unwrap();
53-
server.await
54-
})
55-
});
56-
57-
let server_handle = rx.recv().unwrap();
58-
59-
TestServerRuntime {
60-
addr: "127.0.0.1:0".parse().unwrap(),
61-
host: "127.0.0.1".to_string(),
62-
port: 0,
63-
server_handle,
64-
thread_handle: Some(thread_handle),
65-
}
41+
/// Start new `TestServer` using application factory and default server config.
42+
pub fn start(factory: impl ServerServiceFactory<TcpStream>) -> TestServerHandle {
43+
Self::start_with_builder(Server::build(), factory)
6644
}
6745

68-
/// Start new test server with application factory.
69-
pub fn with<F: ServerServiceFactory<TcpStream>>(factory: F) -> TestServerRuntime {
46+
/// Start new `TestServer` using application factory and server builder.
47+
pub fn start_with_builder(
48+
server_builder: ServerBuilder,
49+
factory: impl ServerServiceFactory<TcpStream>,
50+
) -> TestServerHandle {
7051
let (tx, rx) = mpsc::channel();
7152

7253
// run server in separate thread
7354
let thread_handle = thread::spawn(move || {
74-
let sys = System::new();
75-
let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
76-
let local_addr = tcp.local_addr().unwrap();
55+
let lst = net::TcpListener::bind("127.0.0.1:0").unwrap();
56+
let local_addr = lst.local_addr().unwrap();
7757

78-
sys.block_on(async {
79-
let server = Server::build()
80-
.listen("test", tcp, factory)
58+
System::new().block_on(async {
59+
let server = server_builder
60+
.listen("test", lst, factory)
8161
.unwrap()
8262
.workers(1)
8363
.disable_signals()
@@ -93,7 +73,7 @@ impl TestServer {
9373
let host = format!("{}", addr.ip());
9474
let port = addr.port();
9575

96-
TestServerRuntime {
76+
TestServerHandle {
9777
addr,
9878
host,
9979
port,
@@ -107,17 +87,19 @@ impl TestServer {
10787
use socket2::{Domain, Protocol, Socket, Type};
10888

10989
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
110-
let socket =
111-
Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP)).unwrap();
90+
let domain = Domain::for_address(addr);
91+
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP)).unwrap();
92+
11293
socket.set_reuse_address(true).unwrap();
11394
socket.set_nonblocking(true).unwrap();
11495
socket.bind(&addr.into()).unwrap();
11596
socket.listen(1024).unwrap();
97+
11698
net::TcpListener::from(socket).local_addr().unwrap()
11799
}
118100
}
119101

120-
impl TestServerRuntime {
102+
impl TestServerHandle {
121103
/// Test server host.
122104
pub fn host(&self) -> &str {
123105
&self.host
@@ -140,12 +122,12 @@ impl TestServerRuntime {
140122
}
141123

142124
/// Connect to server, returning a Tokio `TcpStream`.
143-
pub fn connect(&self) -> std::io::Result<TcpStream> {
125+
pub fn connect(&self) -> io::Result<TcpStream> {
144126
TcpStream::from_std(net::TcpStream::connect(self.addr)?)
145127
}
146128
}
147129

148-
impl Drop for TestServerRuntime {
130+
impl Drop for TestServerHandle {
149131
fn drop(&mut self) {
150132
self.stop()
151133
}
@@ -158,8 +140,14 @@ mod tests {
158140
use super::*;
159141

160142
#[tokio::test]
161-
async fn plain_tokio_runtime() {
162-
let srv = TestServer::with(|| fn_service(|_sock| async move { Ok::<_, ()>(()) }));
143+
async fn connect_in_tokio_runtime() {
144+
let srv = TestServer::start(|| fn_service(|_sock| async move { Ok::<_, ()>(()) }));
145+
assert!(srv.connect().is_ok());
146+
}
147+
148+
#[actix_rt::test]
149+
async fn connect_in_actix_runtime() {
150+
let srv = TestServer::start(|| fn_service(|_sock| async move { Ok::<_, ()>(()) }));
163151
assert!(srv.connect().is_ok());
164152
}
165153
}

actix-server/tests/test_server.rs renamed to actix-server/tests/server.rs

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -79,35 +79,6 @@ fn test_listen() {
7979
h.join().unwrap().unwrap();
8080
}
8181

82-
// #[test]
83-
// fn test_bind() {
84-
// let addr = unused_addr();
85-
// let (tx, rx) = mpsc::channel();
86-
87-
// let h = thread::spawn(move || {
88-
// actix_rt::System::new().block_on(async {
89-
// let srv = Server::build()
90-
// .workers(1)
91-
// .disable_signals()
92-
// .bind("test", addr, move || {
93-
// fn_service(|_| async { Ok::<_, ()>(()) })
94-
// })?
95-
// .run();
96-
97-
// let _ = tx.send(srv.handle());
98-
99-
// srv.await
100-
// })
101-
// });
102-
// let srv = rx.recv().unwrap();
103-
104-
// thread::sleep(Duration::from_millis(500));
105-
// assert!(net::TcpStream::connect(addr).is_ok());
106-
107-
// let _ = srv.stop(true);
108-
// h.join().unwrap().unwrap();
109-
// }
110-
11182
#[test]
11283
fn plain_tokio_runtime() {
11384
let addr = unused_addr();
@@ -143,38 +114,6 @@ fn plain_tokio_runtime() {
143114
h.join().unwrap().unwrap();
144115
}
145116

146-
// #[test]
147-
// fn test_listen() {
148-
// let addr = unused_addr();
149-
// let lst = net::TcpListener::bind(addr).unwrap();
150-
151-
// let (tx, rx) = mpsc::channel();
152-
153-
// let h = thread::spawn(move || {
154-
// actix_rt::System::new().block_on(async {
155-
// let srv = Server::build()
156-
// .disable_signals()
157-
// .workers(1)
158-
// .listen("test", lst, move || {
159-
// fn_service(|_| async { Ok::<_, ()>(()) })
160-
// })?
161-
// .run();
162-
163-
// let _ = tx.send(srv.handle());
164-
165-
// srv.await
166-
// })
167-
// });
168-
169-
// let srv = rx.recv().unwrap();
170-
171-
// thread::sleep(Duration::from_millis(500));
172-
// assert!(net::TcpStream::connect(addr).is_ok());
173-
174-
// let _ = srv.stop(true);
175-
// h.join().unwrap().unwrap();
176-
// }
177-
178117
#[test]
179118
#[cfg(unix)]
180119
fn test_start() {

actix-server/tests/testing_server.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use std::net;
2+
3+
use actix_rt::net::TcpStream;
4+
use actix_server::{Server, TestServer};
5+
use actix_service::fn_service;
6+
use bytes::BytesMut;
7+
use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _};
8+
9+
macro_rules! await_timeout_ms {
10+
($fut:expr, $limit:expr) => {
11+
::actix_rt::time::timeout(::std::time::Duration::from_millis($limit), $fut)
12+
.await
13+
.unwrap()
14+
.unwrap();
15+
};
16+
}
17+
18+
#[tokio::test]
19+
async fn testing_server_echo() {
20+
let srv = TestServer::start(|| {
21+
fn_service(move |mut stream: TcpStream| async move {
22+
let mut size = 0;
23+
let mut buf = BytesMut::new();
24+
25+
match stream.read_buf(&mut buf).await {
26+
Ok(0) => return Err(()),
27+
28+
Ok(bytes_read) => {
29+
stream.write_all(&buf[size..]).await.unwrap();
30+
size += bytes_read;
31+
}
32+
33+
Err(_) => return Err(()),
34+
}
35+
36+
Ok((buf.freeze(), size))
37+
})
38+
});
39+
40+
let mut conn = srv.connect().unwrap();
41+
42+
await_timeout_ms!(conn.write_all(b"test"), 200);
43+
44+
let mut buf = Vec::new();
45+
await_timeout_ms!(conn.read_to_end(&mut buf), 200);
46+
47+
assert_eq!(&buf, b"test".as_ref());
48+
}
49+
50+
#[tokio::test]
51+
async fn new_with_builder() {
52+
let alt_addr = TestServer::unused_addr();
53+
54+
let srv = TestServer::start_with_builder(
55+
Server::build()
56+
.bind("alt", alt_addr, || {
57+
fn_service(|_| async { Ok::<_, ()>(()) })
58+
})
59+
.unwrap(),
60+
|| {
61+
fn_service(|mut sock: TcpStream| async move {
62+
let mut buf = [0u8; 16];
63+
sock.read_exact(&mut buf).await
64+
})
65+
},
66+
);
67+
68+
// connect to test server
69+
srv.connect().unwrap();
70+
71+
// connect to alt service defined in custom ServerBuilder
72+
TcpStream::from_std(net::TcpStream::connect(alt_addr).unwrap()).unwrap();
73+
}

actix-tls/tests/accept-openssl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fn rustls_connector(_cert: String, _key: String) -> ClientConfig {
9494
async fn accepts_connections() {
9595
let (cert, key) = new_cert_and_key();
9696

97-
let srv = TestServer::with({
97+
let srv = TestServer::start({
9898
let cert = cert.clone();
9999
let key = key.clone();
100100

actix-tls/tests/accept-rustls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ fn openssl_connector(cert: String, key: String) -> SslConnector {
7474
async fn accepts_connections() {
7575
let (cert, key) = new_cert_and_key();
7676

77-
let srv = TestServer::with({
77+
let srv = TestServer::start({
7878
let cert = cert.clone();
7979
let key = key.clone();
8080

actix-tls/tests/test_connect.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use actix_tls::connect::{ConnectError, ConnectInfo, Connection, Connector, Host}
1717
#[cfg(feature = "openssl")]
1818
#[actix_rt::test]
1919
async fn test_string() {
20-
let srv = TestServer::with(|| {
20+
let srv = TestServer::start(|| {
2121
fn_service(|io: TcpStream| async {
2222
let mut framed = Framed::new(io, BytesCodec);
2323
framed.send(Bytes::from_static(b"test")).await?;
@@ -34,7 +34,7 @@ async fn test_string() {
3434
#[cfg(feature = "rustls")]
3535
#[actix_rt::test]
3636
async fn test_rustls_string() {
37-
let srv = TestServer::with(|| {
37+
let srv = TestServer::start(|| {
3838
fn_service(|io: TcpStream| async {
3939
let mut framed = Framed::new(io, BytesCodec);
4040
framed.send(Bytes::from_static(b"test")).await?;
@@ -50,7 +50,7 @@ async fn test_rustls_string() {
5050

5151
#[actix_rt::test]
5252
async fn test_static_str() {
53-
let srv = TestServer::with(|| {
53+
let srv = TestServer::start(|| {
5454
fn_service(|io: TcpStream| async {
5555
let mut framed = Framed::new(io, BytesCodec);
5656
framed.send(Bytes::from_static(b"test")).await?;
@@ -81,7 +81,7 @@ async fn service_factory() {
8181
Connector::default()
8282
}
8383

84-
let srv = TestServer::with(|| {
84+
let srv = TestServer::start(|| {
8585
fn_service(|io: TcpStream| async {
8686
let mut framed = Framed::new(io, BytesCodec);
8787
framed.send(Bytes::from_static(b"test")).await?;
@@ -101,7 +101,7 @@ async fn service_factory() {
101101
async fn test_openssl_uri() {
102102
use std::convert::TryFrom;
103103

104-
let srv = TestServer::with(|| {
104+
let srv = TestServer::start(|| {
105105
fn_service(|io: TcpStream| async {
106106
let mut framed = Framed::new(io, BytesCodec);
107107
framed.send(Bytes::from_static(b"test")).await?;
@@ -120,7 +120,7 @@ async fn test_openssl_uri() {
120120
async fn test_rustls_uri() {
121121
use std::convert::TryFrom;
122122

123-
let srv = TestServer::with(|| {
123+
let srv = TestServer::start(|| {
124124
fn_service(|io: TcpStream| async {
125125
let mut framed = Framed::new(io, BytesCodec);
126126
framed.send(Bytes::from_static(b"test")).await?;
@@ -136,7 +136,7 @@ async fn test_rustls_uri() {
136136

137137
#[actix_rt::test]
138138
async fn test_local_addr() {
139-
let srv = TestServer::with(|| {
139+
let srv = TestServer::start(|| {
140140
fn_service(|io: TcpStream| async {
141141
let mut framed = Framed::new(io, BytesCodec);
142142
framed.send(Bytes::from_static(b"test")).await?;

0 commit comments

Comments
 (0)