128 lines
3.9 KiB
Rust
128 lines
3.9 KiB
Rust
//! Tests for `BrokerPort` when the broker's frames break the protocol. Every one ends in the same
|
|
//! plain failure and one printed line. Do not edit.
|
|
|
|
#[path = "support/broker.rs"]
|
|
mod fake;
|
|
|
|
use std::io::Write;
|
|
use std::os::unix::net::UnixStream;
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
use fake::{assert_unavailable, broker, call, frame, in_ms, request, result, send};
|
|
use proto::{Envelope, ErrorCode, Message, PROTOCOL_VERSION, ToolResponse, WireError, write_frame};
|
|
|
|
#[test]
|
|
fn frames_that_break_the_protocol_are_unavailable() {
|
|
type Script = Box<dyn FnOnce(&mut UnixStream, &Envelope) + Send>;
|
|
let pending = |approval| ToolResponse::PendingApproval {
|
|
approval,
|
|
expires: in_ms(60_000),
|
|
};
|
|
let cases: Vec<(&str, Script)> = vec![
|
|
(
|
|
"an answer for another request id",
|
|
Box::new(|s, r| send(s, r.id + 1, true, result("x"))),
|
|
),
|
|
(
|
|
"a final frame that is pending",
|
|
Box::new(move |s, r| send(s, r.id, true, pending(1))),
|
|
),
|
|
(
|
|
"an answer that is not final",
|
|
Box::new(|s, r| send(s, r.id, false, result("x"))),
|
|
),
|
|
(
|
|
"a second pending frame",
|
|
Box::new(move |s, r| {
|
|
send(s, r.id, false, pending(1));
|
|
send(s, r.id, false, pending(2));
|
|
thread::sleep(Duration::from_millis(100));
|
|
}),
|
|
),
|
|
(
|
|
"pending, then another id",
|
|
Box::new(move |s, r| {
|
|
send(s, r.id, false, pending(1));
|
|
send(s, r.id + 1, true, result("x"));
|
|
}),
|
|
),
|
|
(
|
|
"an error message",
|
|
Box::new(|s, r| {
|
|
let error = Message::Error(WireError {
|
|
code: ErrorCode::Forbidden,
|
|
detail: "tool requests only".to_string(),
|
|
});
|
|
let _ = write_frame(s, &frame(r.id, true, error));
|
|
}),
|
|
),
|
|
(
|
|
"a message of another kind",
|
|
Box::new(|s, r| {
|
|
let echo = Message::ToolRequest(request());
|
|
let _ = write_frame(s, &frame(r.id, true, echo));
|
|
}),
|
|
),
|
|
(
|
|
"another protocol version",
|
|
Box::new(|s, r| {
|
|
let mut env = frame(r.id, true, Message::ToolResponse(result("x")));
|
|
env.v = PROTOCOL_VERSION + 1;
|
|
let _ = write_frame(s, &env);
|
|
}),
|
|
),
|
|
(
|
|
"a zero length",
|
|
Box::new(|s, _| {
|
|
let _ = s.write_all(&[0, 0, 0, 0]);
|
|
}),
|
|
),
|
|
(
|
|
"a length over the maximum",
|
|
Box::new(|s, _| {
|
|
let _ = s.write_all(&[0xff, 0xff, 0xff, 0xff]);
|
|
}),
|
|
),
|
|
(
|
|
"a body that is not JSON",
|
|
Box::new(|s, _| {
|
|
let _ = s.write_all(&[0, 0, 0, 5]);
|
|
let _ = s.write_all(b"hello");
|
|
}),
|
|
),
|
|
(
|
|
"a body cut short",
|
|
Box::new(|s, _| {
|
|
let _ = s.write_all(&[0, 0, 0, 50]);
|
|
let _ = s.write_all(b"{\"v\":1");
|
|
}),
|
|
),
|
|
];
|
|
for (why, script) in cases {
|
|
let (socket, broker) = broker(script);
|
|
let got = call(socket, 1_000, &request());
|
|
assert_unavailable(&got, why);
|
|
broker.join().unwrap();
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn the_error_message_the_broker_sent_is_in_the_line() {
|
|
let (socket, broker) = broker(|s, r| {
|
|
let error = Message::Error(WireError {
|
|
code: ErrorCode::Internal,
|
|
detail: "the ledger is gone".to_string(),
|
|
});
|
|
let _ = write_frame(s, &frame(r.id, true, error));
|
|
});
|
|
let got = call(socket, 1_000, &request());
|
|
assert_unavailable(&got, "an error message");
|
|
assert!(
|
|
got.lines[0].contains("the ledger is gone"),
|
|
"{}",
|
|
got.lines[0]
|
|
);
|
|
broker.join().unwrap();
|
|
}
|