Done the way the owner asked and the spike mapped: the crate and the manifests renamed, then what the build reported fixed. Layers: 138 "proto unresolved" errors across 169 files; cargo fmt reordering imports; six fixture paths built as strings in brokerd's and bxctl's tests, which the compiler cannot see, and comments naming crates/proto/; the crate-dependency check and its self-test. One more the spike did not reach: a `\nproto =` key inside a printf format in the self-test, which a word-boundary replacement skips because `n` and `p` are both word characters. make gate: gate: ok, 944 tests; no new entry in /tmp. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
130 lines
3.9 KiB
Rust
130 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 bxcore::{
|
|
Envelope, ErrorCode, Message, PROTOCOL_VERSION, ToolResponse, WireError, write_frame,
|
|
};
|
|
use fake::{assert_unavailable, broker, call, frame, in_ms, request, result, send};
|
|
|
|
#[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();
|
|
}
|