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