//! 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; 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(); }