use std::io::Write;
use std::net::{SocketAddr, TcpListener, TcpStream};
use super::{AcceptorSettings, HandshakeSupervisor};
use crate::server::connection::ConnectionSupervisor;
fn acceptor_settings() -> AcceptorSettings {
AcceptorSettings {
path: "/liminal".to_owned(),
allowed_origins: Vec::new(),
ping_interval: None,
message_bound: 1024,
}
}
fn connected_pair(
listener: &TcpListener,
) -> Result<(TcpStream, SocketAddr, TcpStream), Box<dyn std::error::Error>> {
let address = listener.local_addr()?;
let client = TcpStream::connect(address)?;
let (server, peer) = listener.accept()?;
Ok((server, peer, client))
}
#[test]
fn handshake_worker_completion_delivered_not_reap_scanned() -> Result<(), Box<dyn std::error::Error>>
{
let supervisor = ConnectionSupervisor::new()?;
let handshakes = HandshakeSupervisor::new(supervisor.clone(), acceptor_settings());
let listener = TcpListener::bind("127.0.0.1:0")?;
let (server_one, peer_one, client_one) = connected_pair(&listener)?;
drop(client_one);
handshakes.begin(server_one, Some(peer_one));
let (server_two, peer_two, mut client_two) = connected_pair(&listener)?;
client_two.write_all(
b"GET /wrong HTTP/1.1\r\n\
Host: server.example.com\r\n\
Connection: Upgrade\r\n\
Upgrade: websocket\r\n\
Sec-WebSocket-Version: 13\r\n\
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n",
)?;
handshakes.begin(server_two, Some(peer_two));
handshakes.wait_for_completions(2);
assert_eq!(
handshakes.worker_record_count(),
0,
"never-registering handshake workers must be reclaimed by their own \
completion delivery, leaving no worker record"
);
let accept_loop_source = include_str!("listener.rs");
assert!(
!accept_loop_source.contains("reap_finished"),
"the WebSocket accept loop must not call a handshake reap join-scan"
);
let supervisor_source = include_str!("supervisor.rs");
assert!(
!supervisor_source.contains("reap_finished"),
"the handshake supervisor must not retain a reap_finished join-scan"
);
assert!(
!supervisor_source.contains("is_finished"),
"completion delivery must not sample worker liveness with is_finished"
);
drop(client_two);
handshakes.stop();
supervisor.shutdown();
Ok(())
}