Skip to content

Commit 420e9a3

Browse files
Add an integration test for SyslogBuilder.
1 parent bc7991b commit 420e9a3

File tree

1 file changed

+95
-28
lines changed

1 file changed

+95
-28
lines changed

tests/test.rs

Lines changed: 95 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,83 @@ extern crate syslog;
44

55
use slog::*;
66
use slog_syslog::*;
7-
use std::net::UdpSocket;
7+
use std::net::{SocketAddr, UdpSocket};
88
use std::sync::Mutex;
99
use std::thread;
1010
use std::time::Duration;
1111

12-
#[test]
13-
fn integration_test() {
14-
let server_socket = UdpSocket::bind("localhost:0").expect("couldn't bind server socket");
15-
let server_addr = server_socket.local_addr().expect("couldn't get server socket address");
12+
mod test_server {
13+
use super::*;
14+
15+
#[derive(Debug)]
16+
#[must_use = "the test server does nothing useful unless you send something to it"]
17+
pub struct TestServer {
18+
pub server_addr: SocketAddr,
19+
server_thread: Option<thread::JoinHandle<Vec<Box<[u8]>>>>,
20+
pub client_addr: SocketAddr,
21+
}
1622

17-
// Start a server.
18-
let server_thread = thread::spawn(move || {
19-
server_socket.set_read_timeout(Some(Duration::from_secs(10))).expect("couldn't set server socket read timeout");
23+
impl TestServer {
24+
pub fn new() -> Self {
25+
let server_socket = UdpSocket::bind("localhost:0").expect("couldn't bind server socket");
26+
server_socket.set_read_timeout(Some(Duration::from_secs(10))).expect("couldn't set server socket read timeout");
2027

21-
let mut packets = Vec::<Box<[u8]>>::new();
22-
let mut buf = [0u8; 65535];
28+
let server_addr = server_socket.local_addr().expect("couldn't get server socket address");
29+
30+
let client_addr = {
31+
let mut client_addr = server_addr.clone();
32+
client_addr.set_port(0);
33+
client_addr
34+
};
35+
36+
let server_thread = Some(thread::spawn(move || {
37+
let mut packets = Vec::<Box<[u8]>>::new();
38+
let mut buf = [0u8; 65535];
39+
40+
loop {
41+
let (pkt_size, _) = server_socket.recv_from(&mut buf).expect("server couldn't receive packet");
42+
43+
if pkt_size == 4 && &buf[0..4] == b"STOP" {
44+
break;
45+
}
46+
47+
packets.push(Box::from(&buf[..pkt_size]));
48+
}
49+
50+
packets
51+
}));
52+
53+
TestServer { server_thread, server_addr, client_addr }
54+
}
2355

24-
loop {
25-
let (pkt_size, _) = server_socket.recv_from(&mut buf).expect("server couldn't receive packet");
56+
pub fn finish(mut self) -> Vec<Box<[u8]>> {
57+
let server_thread = self.server_thread.take().expect("server thread already stopped");
2658

27-
if pkt_size == 4 && &buf[0..4] == b"STOP" {
28-
break;
59+
{
60+
let client_socket = UdpSocket::bind(self.client_addr).expect("couldn't bind client socket");
61+
client_socket.send_to(b"STOP", &self.server_addr).expect("couldn't send stop packet");
2962
}
3063

31-
packets.push(Box::from(&buf[..pkt_size]));
64+
server_thread.join().expect("server thread panicked")
3265
}
66+
}
3367

34-
packets
35-
});
68+
impl Drop for TestServer {
69+
fn drop(&mut self) {
70+
if self.server_thread.is_some() {
71+
// Try to stop the server thread. Ignore errors, since this will probably only happen when an error or panic has already occurred.
72+
if let Ok(client_socket) = UdpSocket::bind(self.client_addr) {
73+
let _ = client_socket.send_to(b"STOP", &self.server_addr);
74+
}
75+
}
76+
}
77+
}
78+
}
79+
use test_server::TestServer;
3680

37-
let client_addr = {
38-
let mut client_addr = server_addr.clone();
39-
client_addr.set_port(0);
40-
client_addr
41-
};
81+
#[test]
82+
fn integration_test() {
83+
let server = TestServer::new();
4284

4385
{
4486
// Set up a logger.
@@ -50,8 +92,8 @@ fn integration_test() {
5092
process: "test-app".to_string(),
5193
pid: 123
5294
},
53-
&client_addr,
54-
&server_addr
95+
&server.client_addr,
96+
&server.server_addr
5597
).expect("couldn't create syslog logger"))).fuse(),
5698
o!("key" => "value")
5799
);
@@ -60,14 +102,39 @@ fn integration_test() {
60102
info!(logger, "Hello, world!"; "key2" => "value2");
61103
}
62104

105+
// Get the logs received by the server thread.
106+
let logs = server.finish();
107+
108+
// Check that the logs were correct.
109+
assert_eq!(logs.len(), 1);
110+
111+
let s = String::from_utf8(logs[0].to_vec()).expect("log packet contains invalid UTF-8");
112+
assert!(s.starts_with("<14>"));
113+
assert!(s.ends_with("test-hostname test-app[123]: Hello, world! [key=\"value\" key2=\"value2\"]"));
114+
}
115+
116+
#[test]
117+
fn integration_test_with_builder() {
118+
let server = TestServer::new();
119+
63120
{
64-
// Tell the server thread to stop.
65-
let client_socket = UdpSocket::bind(client_addr).expect("couldn't bind client socket");
66-
client_socket.send_to(b"STOP", &server_addr).expect("couldn't send stop packet");
121+
// Set up a logger.
122+
let drain = SyslogBuilder::new()
123+
.hostname("test-hostname")
124+
.process("test-app")
125+
.pid(123)
126+
.udp(server.client_addr, server.server_addr)
127+
.start()
128+
.expect("couldn't create syslog logger");
129+
130+
let logger = Logger::root_typed(drain.fuse(), o!("key" => "value"));
131+
132+
// Log a test message.
133+
info!(logger, "Hello, world!"; "key2" => "value2");
67134
}
68135

69136
// Get the logs received by the server thread.
70-
let logs = server_thread.join().expect("server thread panicked");
137+
let logs = server.finish();
71138

72139
// Check that the logs were correct.
73140
assert_eq!(logs.len(), 1);

0 commit comments

Comments
 (0)