@@ -4,41 +4,83 @@ extern crate syslog;
4
4
5
5
use slog:: * ;
6
6
use slog_syslog:: * ;
7
- use std:: net:: UdpSocket ;
7
+ use std:: net:: { SocketAddr , UdpSocket } ;
8
8
use std:: sync:: Mutex ;
9
9
use std:: thread;
10
10
use std:: time:: Duration ;
11
11
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
+ }
16
22
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" ) ;
20
27
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
+ }
23
55
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 " ) ;
26
58
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" ) ;
29
62
}
30
63
31
- packets . push ( Box :: from ( & buf [ ..pkt_size ] ) ) ;
64
+ server_thread . join ( ) . expect ( "server thread panicked" )
32
65
}
66
+ }
33
67
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 ;
36
80
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 ( ) ;
42
84
43
85
{
44
86
// Set up a logger.
@@ -50,8 +92,8 @@ fn integration_test() {
50
92
process : "test-app" . to_string ( ) ,
51
93
pid : 123
52
94
} ,
53
- & client_addr,
54
- & server_addr
95
+ & server . client_addr ,
96
+ & server . server_addr
55
97
) . expect ( "couldn't create syslog logger" ) ) ) . fuse ( ) ,
56
98
o ! ( "key" => "value" )
57
99
) ;
@@ -60,14 +102,39 @@ fn integration_test() {
60
102
info ! ( logger, "Hello, world!" ; "key2" => "value2" ) ;
61
103
}
62
104
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
+
63
120
{
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" ) ;
67
134
}
68
135
69
136
// Get the logs received by the server thread.
70
- let logs = server_thread . join ( ) . expect ( "server thread panicked" ) ;
137
+ let logs = server . finish ( ) ;
71
138
72
139
// Check that the logs were correct.
73
140
assert_eq ! ( logs. len( ) , 1 ) ;
0 commit comments