()
| 162 | |
| 163 | #[tokio::test] |
| 164 | async fn test_tcp_forward_roundtrip() { |
| 165 | // Echo server |
| 166 | let echo = TcpListener::bind("127.0.0.1:0").await.unwrap(); |
| 167 | let echo_addr = echo.local_addr().unwrap(); |
| 168 | tokio::spawn(async move { |
| 169 | loop { |
| 170 | let (mut conn, _) = echo.accept().await.unwrap(); |
| 171 | tokio::spawn(async move { |
| 172 | let mut buf = vec![0u8; 4096]; |
| 173 | loop { |
| 174 | let n = match conn.read(&mut buf).await { |
| 175 | Ok(0) | Err(_) => break, |
| 176 | Ok(n) => n, |
| 177 | }; |
| 178 | if conn.write_all(&buf[..n]).await.is_err() { |
| 179 | break; |
| 180 | } |
| 181 | } |
| 182 | }); |
| 183 | } |
| 184 | }); |
| 185 | |
| 186 | // Start forwarder on a free port |
| 187 | let tmp = TcpListener::bind("127.0.0.1:0").await.unwrap(); |
| 188 | let fwd_addr = tmp.local_addr().unwrap(); |
| 189 | drop(tmp); |
| 190 | |
| 191 | let cancel = CancellationToken::new(); |
| 192 | tokio::spawn(run_tcp_forwarder(fwd_addr, echo_addr, cancel.child_token())); |
| 193 | tokio::time::sleep(std::time::Duration::from_millis(50)).await; |
| 194 | |
| 195 | let mut conn = TcpStream::connect(fwd_addr).await.unwrap(); |
| 196 | conn.write_all(b"hello splice").await.unwrap(); |
| 197 | |
| 198 | let mut buf = vec![0u8; 64]; |
| 199 | let n = tokio::time::timeout(std::time::Duration::from_secs(2), conn.read(&mut buf)) |
| 200 | .await |
| 201 | .unwrap() |
| 202 | .unwrap(); |
| 203 | assert_eq!(&buf[..n], b"hello splice"); |
| 204 | |
| 205 | cancel.cancel(); |
| 206 | } |
| 207 | } |
nothing calls this directly
no test coverage detected