//! Integration test for v3.1 multi-hop control envelope payloads (`ExtendBridge`). //! //! Mirrors `frame.rs`'s in-crate unit coverage but at the integration level so an external //! consumer of `aura-proto` (the CLI's `circuit` module) sees the same wire layout. use std::net::SocketAddr; use aura_proto::{ decode_control_envelope, decode_extend_bridge, encode_control_envelope, encode_extend_bridge, ControlKind, }; #[test] fn extend_bridge_payload_roundtrips_ipv4() { let addr: SocketAddr = "203.0.113.42:443".parse().unwrap(); let payload = encode_extend_bridge(addr); assert_eq!(payload.len(), 1 + 4 + 2); let got = decode_extend_bridge(&payload).expect("decode v4"); assert_eq!(got, addr); } #[test] fn extend_bridge_payload_roundtrips_ipv6() { let addr: SocketAddr = "[2001:db8::dead:beef]:1234".parse().unwrap(); let payload = encode_extend_bridge(addr); assert_eq!(payload.len(), 1 + 16 + 2); let got = decode_extend_bridge(&payload).expect("decode v6"); assert_eq!(got, addr); } #[test] fn extend_bridge_via_full_envelope() { // Build the bytes the client actually sends over the wire: the envelope wraps the payload. let addr: SocketAddr = "10.0.0.5:443".parse().unwrap(); let payload = encode_extend_bridge(addr); let envelope = encode_control_envelope(ControlKind::ExtendBridge, &payload); let (kind, decoded_payload) = decode_control_envelope(&envelope).unwrap().unwrap(); assert_eq!(kind, ControlKind::ExtendBridge); let got_addr = decode_extend_bridge(&decoded_payload).expect("decode addr from envelope"); assert_eq!(got_addr, addr); } #[test] fn extend_bridge_rejects_malformed_payload() { assert!(decode_extend_bridge(&[]).is_err()); assert!(decode_extend_bridge(&[4u8]).is_err()); // family but truncated assert!(decode_extend_bridge(&[4u8, 1, 2, 3, 4]).is_err()); // missing port bytes assert!(decode_extend_bridge(&[4u8, 1, 2, 3, 4, 0, 0, 99]).is_err()); // extra byte assert!(decode_extend_bridge(&[6u8, 0, 0]).is_err()); // v6 truncated assert!(decode_extend_bridge(&[7u8, 0, 0, 0, 0, 0, 0]).is_err()); // unknown family } #[test] fn circuit_ready_envelope_has_empty_payload() { let envelope = encode_control_envelope(ControlKind::CircuitReady, &[]); let (kind, payload) = decode_control_envelope(&envelope).unwrap().unwrap(); assert_eq!(kind, ControlKind::CircuitReady); assert!(payload.is_empty()); } #[test] fn circuit_failed_carries_utf8_reason() { let envelope = encode_control_envelope(ControlKind::CircuitFailed, b"not in allow_extend_to"); let (kind, payload) = decode_control_envelope(&envelope).unwrap().unwrap(); assert_eq!(kind, ControlKind::CircuitFailed); assert_eq!( std::str::from_utf8(&payload).unwrap(), "not in allow_extend_to" ); }