Files
fips/src/proto/lookup/tests/wire.rs
T
Johnathan Corgan c5d48e5ef4 Merge refactor-sans-io: rename proto/discovery to proto/lookup into the next line
Forward-merge the mesh discovery module rename (directory, exported types, and
internal lookup-stem terminology) onto the next wire-format line. next's
divergent lookup wire and core content is preserved under the new proto/lookup
path, with the same terminology sweep applied to its next-only lines.
2026-07-08 21:54:24 +00:00

240 lines
7.7 KiB
Rust

//! Tests for the lookup wire codec (`LookupRequest` / `LookupResponse`).
use super::util::{make_coords, signed_response};
use crate::proto::lookup::{LookupRequest, LookupResponse};
use crate::testutil::make_node_addr;
#[test]
fn test_lookup_request_forward() {
let target = make_node_addr(1);
let origin = make_node_addr(2);
let mut request = LookupRequest::new(123, target, origin, 5, 0);
assert!(request.can_forward());
assert!(request.forward());
assert_eq!(request.ttl, 4);
}
#[test]
fn test_lookup_request_ttl_exhausted() {
let target = make_node_addr(1);
let origin = make_node_addr(2);
let mut request = LookupRequest::new(123, target, origin, 1, 0);
assert!(request.forward());
assert!(!request.can_forward());
assert!(!request.forward());
}
#[test]
fn test_lookup_request_generate() {
let target = make_node_addr(1);
let origin = make_node_addr(2);
use rand::RngExt;
let req1 = LookupRequest::new(rand::rng().random(), target, origin, 5, 0);
let req2 = LookupRequest::new(rand::rng().random(), target, origin, 5, 0);
// Random IDs should differ
assert_ne!(req1.request_id, req2.request_id);
}
#[test]
fn test_lookup_response_proof_bytes() {
let target = make_node_addr(42);
let coords = make_coords(&[42, 1, 0]);
let bytes = LookupResponse::proof_bytes(12345, &target, &coords);
// 8 (request_id) + 16 (target) + 2 (count) + 3*16 (coords) = 74
assert_eq!(bytes.len(), 74);
assert_eq!(&bytes[0..8], &12345u64.to_le_bytes());
assert_eq!(&bytes[8..24], target.as_bytes());
// Verify coordinate encoding is present
let count = u16::from_le_bytes([bytes[24], bytes[25]]);
assert_eq!(count, 3); // 3 entries in coords
}
#[test]
fn test_lookup_request_encode_decode_roundtrip() {
let target = make_node_addr(10);
let origin = make_node_addr(20);
let mut request = LookupRequest::new(12345, target, origin, 8, 1386);
request.forward();
let encoded = request.encode();
assert_eq!(encoded[0], 0x30);
let decoded = LookupRequest::decode(&encoded[1..]).unwrap();
assert_eq!(decoded.request_id, 12345);
assert_eq!(decoded.target, target);
assert_eq!(decoded.origin, origin);
assert_eq!(decoded.ttl, 7); // decremented by forward()
assert_eq!(decoded.min_mtu, 1386);
}
#[test]
fn test_lookup_request_decode_too_short() {
assert!(LookupRequest::decode(&[]).is_err());
assert!(LookupRequest::decode(&[0u8; 42]).is_err());
}
#[test]
fn test_lookup_request_min_mtu_boundary_values() {
let target = make_node_addr(10);
let origin = make_node_addr(20);
for mtu_val in [0u16, 1386, u16::MAX] {
let request = LookupRequest::new(100, target, origin, 5, mtu_val);
let encoded = request.encode();
let decoded = LookupRequest::decode(&encoded[1..]).unwrap();
assert_eq!(decoded.min_mtu, mtu_val);
}
}
#[test]
fn test_lookup_response_encode_decode_roundtrip() {
let target = make_node_addr(42);
let coords = make_coords(&[42, 1, 0]);
let response = signed_response(999, &target, &coords);
// Default path_mtu should be u16::MAX
assert_eq!(response.path_mtu, u16::MAX);
let encoded = response.encode();
assert_eq!(encoded[0], 0x31);
let decoded = LookupResponse::decode(&encoded[1..]).unwrap();
assert_eq!(decoded.request_id, 999);
assert_eq!(decoded.target, target);
assert_eq!(decoded.path_mtu, u16::MAX);
assert_eq!(decoded.proof, response.proof);
}
#[test]
fn test_lookup_response_path_mtu_roundtrip() {
let target = make_node_addr(42);
let coords = make_coords(&[42, 1, 0]);
let base = signed_response(999, &target, &coords);
for mtu_val in [0u16, 1280, 1386, 9000, u16::MAX] {
let mut response = base.clone();
response.path_mtu = mtu_val;
let encoded = response.encode();
let decoded = LookupResponse::decode(&encoded[1..]).unwrap();
assert_eq!(decoded.path_mtu, mtu_val);
}
}
#[test]
fn test_lookup_response_path_mtu_not_in_proof_bytes() {
// Verify that proof_bytes does NOT include path_mtu
let target = make_node_addr(42);
let coords = make_coords(&[42, 1, 0]);
let bytes = LookupResponse::proof_bytes(12345, &target, &coords);
// proof_bytes format: request_id(8) + target(16) + coords_encoding(2 + 3*16) = 74
// No path_mtu(2) in here
assert_eq!(bytes.len(), 74);
}
#[test]
fn test_lookup_response_decode_too_short() {
assert!(LookupResponse::decode(&[]).is_err());
assert!(LookupResponse::decode(&[0u8; 50]).is_err());
}
#[test]
fn test_lookup_request_with_tlv_roundtrip() {
let target = make_node_addr(10);
let origin = make_node_addr(20);
let request = LookupRequest::new(555, target, origin, 5, 1280)
.with_tlv(1, vec![0xAA, 0xBB])
.with_tlv(256, vec![0x01, 0x02, 0x03, 0x04]);
let encoded = request.encode();
let decoded = LookupRequest::decode(&encoded[1..]).unwrap();
assert_eq!(decoded.request_id, 555);
assert_eq!(decoded.min_mtu, 1280);
assert_eq!(decoded.tlv_entries.len(), 2);
assert_eq!(decoded.tlv_entries[0].field_num, 1);
assert_eq!(decoded.tlv_entries[0].value, vec![0xAA, 0xBB]);
assert_eq!(decoded.tlv_entries[1].field_num, 256);
assert_eq!(decoded.tlv_entries[1].value, vec![0x01, 0x02, 0x03, 0x04]);
}
#[test]
fn test_lookup_request_tlv_forward_compat() {
// Unknown field_nums should be preserved through decode → forward → encode.
let target = make_node_addr(10);
let origin = make_node_addr(20);
let request =
LookupRequest::new(777, target, origin, 5, 0).with_tlv(9999, vec![0xFF, 0xFE, 0xFD]);
let encoded = request.encode();
let mut decoded = LookupRequest::decode(&encoded[1..]).unwrap();
// Simulate transit: forward then re-encode.
decoded.forward();
let re_encoded = decoded.encode();
let final_decoded = LookupRequest::decode(&re_encoded[1..]).unwrap();
assert_eq!(final_decoded.ttl, 4);
assert_eq!(final_decoded.tlv_entries.len(), 1);
assert_eq!(final_decoded.tlv_entries[0].field_num, 9999);
assert_eq!(final_decoded.tlv_entries[0].value, vec![0xFF, 0xFE, 0xFD]);
}
#[test]
fn test_lookup_response_with_tlv_roundtrip() {
let target = make_node_addr(42);
let coords = make_coords(&[42, 1, 0]);
let response = signed_response(999, &target, &coords)
.with_tlv(1, vec![0xAA, 0xBB])
.with_tlv(500, vec![0x01, 0x02, 0x03]);
let encoded = response.encode();
let decoded = LookupResponse::decode(&encoded[1..]).unwrap();
assert_eq!(decoded.request_id, 999);
assert_eq!(decoded.proof, response.proof);
assert_eq!(decoded.tlv_entries.len(), 2);
assert_eq!(decoded.tlv_entries[0].field_num, 1);
assert_eq!(decoded.tlv_entries[0].value, vec![0xAA, 0xBB]);
assert_eq!(decoded.tlv_entries[1].field_num, 500);
assert_eq!(decoded.tlv_entries[1].value, vec![0x01, 0x02, 0x03]);
}
#[test]
fn test_lookup_response_tlv_forward_compat() {
// Unknown field_nums preserved through decode → modify path_mtu → encode.
let target = make_node_addr(42);
let coords = make_coords(&[42, 1, 0]);
let response = signed_response(999, &target, &coords).with_tlv(9999, vec![0xFF, 0xFE, 0xFD]);
let encoded = response.encode();
let mut decoded = LookupResponse::decode(&encoded[1..]).unwrap();
// Simulate transit: modify path_mtu then re-encode.
decoded.path_mtu = 1280;
let re_encoded = decoded.encode();
let final_decoded = LookupResponse::decode(&re_encoded[1..]).unwrap();
assert_eq!(final_decoded.path_mtu, 1280);
assert_eq!(final_decoded.tlv_entries.len(), 1);
assert_eq!(final_decoded.tlv_entries[0].field_num, 9999);
assert_eq!(final_decoded.tlv_entries[0].value, vec![0xFF, 0xFE, 0xFD]);
}