1 #![warn(rust_2018_idioms)]
2 #![cfg(all(feature = "full", not(target_os = "wasi")))]
3
4 use std::error::Error;
5 use tokio::net::{TcpListener, TcpStream};
6 use tokio::runtime::{Builder, Runtime};
7
8 mod support {
9 pub mod panic;
10 }
11 use support::panic::test_panic;
12
13 #[test]
udp_socket_from_std_panic_caller() -> Result<(), Box<dyn Error>>14 fn udp_socket_from_std_panic_caller() -> Result<(), Box<dyn Error>> {
15 use std::net::SocketAddr;
16 use tokio::net::UdpSocket;
17
18 let addr = "127.0.0.1:0".parse::<SocketAddr>().unwrap();
19 let std_sock = std::net::UdpSocket::bind(addr).unwrap();
20 std_sock.set_nonblocking(true).unwrap();
21
22 let panic_location_file = test_panic(|| {
23 let rt = runtime_without_io();
24 rt.block_on(async {
25 let _sock = UdpSocket::from_std(std_sock);
26 });
27 });
28
29 // The panic location should be in this file
30 assert_eq!(&panic_location_file.unwrap(), file!());
31
32 Ok(())
33 }
34
35 #[test]
tcp_listener_from_std_panic_caller() -> Result<(), Box<dyn Error>>36 fn tcp_listener_from_std_panic_caller() -> Result<(), Box<dyn Error>> {
37 let std_listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
38 std_listener.set_nonblocking(true).unwrap();
39
40 let panic_location_file = test_panic(|| {
41 let rt = runtime_without_io();
42 rt.block_on(async {
43 let _ = TcpListener::from_std(std_listener);
44 });
45 });
46
47 // The panic location should be in this file
48 assert_eq!(&panic_location_file.unwrap(), file!());
49
50 Ok(())
51 }
52
53 #[test]
tcp_stream_from_std_panic_caller() -> Result<(), Box<dyn Error>>54 fn tcp_stream_from_std_panic_caller() -> Result<(), Box<dyn Error>> {
55 let std_listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
56
57 let std_stream = std::net::TcpStream::connect(std_listener.local_addr().unwrap()).unwrap();
58 std_stream.set_nonblocking(true).unwrap();
59
60 let panic_location_file = test_panic(|| {
61 let rt = runtime_without_io();
62 rt.block_on(async {
63 let _ = TcpStream::from_std(std_stream);
64 });
65 });
66
67 // The panic location should be in this file
68 assert_eq!(&panic_location_file.unwrap(), file!());
69
70 Ok(())
71 }
72
73 #[test]
74 #[cfg(unix)]
unix_listener_bind_panic_caller() -> Result<(), Box<dyn Error>>75 fn unix_listener_bind_panic_caller() -> Result<(), Box<dyn Error>> {
76 use tokio::net::UnixListener;
77
78 let dir = tempfile::tempdir().unwrap();
79 let sock_path = dir.path().join("socket");
80
81 let panic_location_file = test_panic(|| {
82 let rt = runtime_without_io();
83 rt.block_on(async {
84 let _ = UnixListener::bind(&sock_path);
85 });
86 });
87
88 // The panic location should be in this file
89 assert_eq!(&panic_location_file.unwrap(), file!());
90
91 Ok(())
92 }
93
94 #[test]
95 #[cfg(unix)]
unix_listener_from_std_panic_caller() -> Result<(), Box<dyn Error>>96 fn unix_listener_from_std_panic_caller() -> Result<(), Box<dyn Error>> {
97 use tokio::net::UnixListener;
98
99 let dir = tempfile::tempdir().unwrap();
100 let sock_path = dir.path().join("socket");
101 let std_listener = std::os::unix::net::UnixListener::bind(&sock_path).unwrap();
102
103 let panic_location_file = test_panic(|| {
104 let rt = runtime_without_io();
105 rt.block_on(async {
106 let _ = UnixListener::from_std(std_listener);
107 });
108 });
109
110 // The panic location should be in this file
111 assert_eq!(&panic_location_file.unwrap(), file!());
112
113 Ok(())
114 }
115
116 #[test]
117 #[cfg(unix)]
unix_stream_from_std_panic_caller() -> Result<(), Box<dyn Error>>118 fn unix_stream_from_std_panic_caller() -> Result<(), Box<dyn Error>> {
119 use tokio::net::UnixStream;
120
121 let dir = tempfile::tempdir().unwrap();
122 let sock_path = dir.path().join("socket");
123 let _std_listener = std::os::unix::net::UnixListener::bind(&sock_path).unwrap();
124 let std_stream = std::os::unix::net::UnixStream::connect(&sock_path).unwrap();
125
126 let panic_location_file = test_panic(|| {
127 let rt = runtime_without_io();
128 rt.block_on(async {
129 let _ = UnixStream::from_std(std_stream);
130 });
131 });
132
133 // The panic location should be in this file
134 assert_eq!(&panic_location_file.unwrap(), file!());
135
136 Ok(())
137 }
138
139 #[test]
140 #[cfg(unix)]
unix_datagram_from_std_panic_caller() -> Result<(), Box<dyn Error>>141 fn unix_datagram_from_std_panic_caller() -> Result<(), Box<dyn Error>> {
142 use std::os::unix::net::UnixDatagram as StdUDS;
143 use tokio::net::UnixDatagram;
144
145 let dir = tempfile::tempdir().unwrap();
146 let sock_path = dir.path().join("socket");
147
148 // Bind the socket to a filesystem path
149 // /let socket_path = tmp.path().join("socket");
150 let std_socket = StdUDS::bind(&sock_path).unwrap();
151 std_socket.set_nonblocking(true).unwrap();
152
153 let panic_location_file = test_panic(move || {
154 let rt = runtime_without_io();
155 rt.block_on(async {
156 let _ = UnixDatagram::from_std(std_socket);
157 });
158 });
159
160 // The panic location should be in this file
161 assert_eq!(&panic_location_file.unwrap(), file!());
162
163 Ok(())
164 }
165
166 #[test]
167 #[cfg(windows)]
server_options_max_instances_panic_caller() -> Result<(), Box<dyn Error>>168 fn server_options_max_instances_panic_caller() -> Result<(), Box<dyn Error>> {
169 use tokio::net::windows::named_pipe::ServerOptions;
170
171 let panic_location_file = test_panic(move || {
172 let rt = runtime_without_io();
173 rt.block_on(async {
174 let mut options = ServerOptions::new();
175 options.max_instances(255);
176 });
177 });
178
179 // The panic location should be in this file
180 assert_eq!(&panic_location_file.unwrap(), file!());
181
182 Ok(())
183 }
184
185 // Runtime without `enable_io` so it has no IO driver set.
runtime_without_io() -> Runtime186 fn runtime_without_io() -> Runtime {
187 Builder::new_current_thread().build().unwrap()
188 }
189