use super::*;
use rustls::ClientConnection;
use rustls::pki_types::ServerName;
use std::net::{Ipv4Addr, TcpStream};
use std::path::Path;
fn stating(dir: &Path, address: &str, version: u32) -> Vec<Value> {
let config = crate::wire::tls::client_config(&material(dir, Role::Client, address))
.expect("client config");
let conn = ClientConnection::new(config, ServerName::IpAddress(Ipv4Addr::LOCALHOST.into()))
.expect("tls");
let tcp = TcpStream::connect(address).expect("connect");
tcp.set_read_timeout(Some(Duration::from_secs(10)))
.expect("timeout");
let mut tls = StreamOwned::new(conn, tcp);
crate::wire::frame::write_value(&mut tls, &json!({ "protocol": version })).expect("preface");
let _ = crate::wire::frame::write_value(&mut tls, &json!({"op": "workspaces"}));
let mut frames = Vec::new();
while let Ok(Some(chunk)) = crate::wire::frame::read_value(&mut tls) {
frames.push(chunk);
}
frames
}
#[test]
fn an_engine_states_its_version_and_answers_a_peer_that_shares_it() {
let (tmp, listener, _seat, asked) = wired(1);
let frames = stating(
tmp.path(),
&listener.address(),
crate::wire::hello::PROTOCOL,
);
assert_eq!(frames.len(), 2, "the preface, then the answer");
assert_eq!(
frames[0],
json!({
"protocol": crate::wire::hello::PROTOCOL,
"edition": crate::wire::hello::EDITION,
})
);
assert_eq!(frames[1]["asked"], json!({"op": "workspaces"}));
assert_eq!(asked.load(Ordering::Relaxed), 1);
}
#[test]
fn a_skewed_peer_is_refused_and_never_reaches_the_answerer() {
let (tmp, listener, _seat, asked) = wired(1);
let frames = stating(
tmp.path(),
&listener.address(),
crate::wire::hello::PROTOCOL + 1,
);
assert_eq!(frames.len(), 2, "the preface, then the refusal");
assert_eq!(frames[1]["ok"], json!(false));
let said = frames[1]["error"].as_str().expect("a sentence");
assert!(said.contains("wire protocol mismatch"), "{said}");
assert!(said.contains("upgrade the older component"), "{said}");
assert_eq!(asked.load(Ordering::Relaxed), 0);
}
#[test]
fn a_seat_of_this_build_is_admitted() {
let (_tmp, _listener, seat, asked) = wired(1);
let stream = seat.ask(&json!({"op": "workspaces"})).expect("answered");
assert_eq!(stream.len(), 1, "the preface is consumed by the dial");
assert_eq!(stream[0]["asked"], json!({"op": "workspaces"}));
assert_eq!(asked.load(Ordering::Relaxed), 1);
}