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