restructure and test, pure python and rust transport both _work_
This commit is contained in:
@@ -10,3 +10,6 @@ serde_json = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { workspace = true, features = ["macros", "rt"] }
|
||||
|
||||
@@ -256,6 +256,117 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// -- P1: Audio packet round-trip --
|
||||
|
||||
#[test]
|
||||
fn audio_packet_round_trip() {
|
||||
let header = PacketHeader {
|
||||
packet_type: PacketType::Audio,
|
||||
flags: 0,
|
||||
length: 256,
|
||||
timestamp_ns: 500_000_000,
|
||||
};
|
||||
let bytes = header.to_bytes();
|
||||
let decoded = PacketHeader::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(decoded.packet_type, PacketType::Audio);
|
||||
assert!(!decoded.is_keyframe());
|
||||
assert_eq!(decoded.length, 256);
|
||||
assert_eq!(decoded.timestamp_ns, 500_000_000);
|
||||
}
|
||||
|
||||
// -- P1: Partial / truncated reads --
|
||||
|
||||
#[test]
|
||||
fn header_rejects_unknown_packet_type() {
|
||||
let mut bytes = [0u8; HEADER_SIZE];
|
||||
bytes[0] = 99; // not 0, 1, or 2
|
||||
assert!(PacketHeader::from_bytes(&bytes).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn header_at_max_payload_size_is_accepted() {
|
||||
let mut bytes = [0u8; HEADER_SIZE];
|
||||
bytes[4..8].copy_from_slice(&MAX_PAYLOAD_SIZE.to_le_bytes());
|
||||
assert!(PacketHeader::from_bytes(&bytes).is_ok());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_packet_truncated_header_returns_error() {
|
||||
// Feed only 8 bytes (half a header) — read_exact should fail.
|
||||
let short_buf: &[u8] = &[0u8; 8];
|
||||
let mut reader = tokio::io::BufReader::new(short_buf);
|
||||
let result = read_packet(&mut reader).await;
|
||||
assert!(result.is_err(), "expected error on truncated header");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_packet_truncated_payload_returns_error() {
|
||||
// Write a valid header claiming 100 bytes of payload, but only provide 50.
|
||||
let header = PacketHeader {
|
||||
packet_type: PacketType::Video,
|
||||
flags: FLAG_KEYFRAME,
|
||||
length: 100,
|
||||
timestamp_ns: 0,
|
||||
};
|
||||
let mut buf = Vec::new();
|
||||
buf.extend_from_slice(&header.to_bytes());
|
||||
buf.extend_from_slice(&[0u8; 50]); // only 50 of the promised 100
|
||||
|
||||
let mut reader = tokio::io::BufReader::new(buf.as_slice());
|
||||
let result = read_packet(&mut reader).await;
|
||||
assert!(result.is_err(), "expected error on truncated payload");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_then_read_round_trip() {
|
||||
let payload: Vec<u8> = (0u8..128).collect();
|
||||
let packet = WirePacket {
|
||||
header: PacketHeader {
|
||||
packet_type: PacketType::Audio,
|
||||
flags: 0,
|
||||
length: payload.len() as u32,
|
||||
timestamp_ns: 999_999_999,
|
||||
},
|
||||
payload: payload.clone(),
|
||||
};
|
||||
|
||||
let mut buf = Vec::new();
|
||||
write_packet(&mut buf, &packet).await.unwrap();
|
||||
|
||||
let mut reader = tokio::io::BufReader::new(buf.as_slice());
|
||||
let decoded = read_packet(&mut reader).await.unwrap();
|
||||
|
||||
assert_eq!(decoded.header.packet_type, PacketType::Audio);
|
||||
assert_eq!(decoded.header.timestamp_ns, 999_999_999);
|
||||
assert_eq!(decoded.payload, payload);
|
||||
}
|
||||
|
||||
// -- P1: Timestamp monotonicity helpers --
|
||||
|
||||
#[test]
|
||||
fn zero_timestamp_is_valid() {
|
||||
let header = PacketHeader {
|
||||
packet_type: PacketType::Video,
|
||||
flags: FLAG_KEYFRAME,
|
||||
length: 0,
|
||||
timestamp_ns: 0,
|
||||
};
|
||||
let decoded = PacketHeader::from_bytes(&header.to_bytes()).unwrap();
|
||||
assert_eq!(decoded.timestamp_ns, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_timestamp_round_trips() {
|
||||
let header = PacketHeader {
|
||||
packet_type: PacketType::Video,
|
||||
flags: 0,
|
||||
length: 0,
|
||||
timestamp_ns: u64::MAX,
|
||||
};
|
||||
let decoded = PacketHeader::from_bytes(&header.to_bytes()).unwrap();
|
||||
assert_eq!(decoded.timestamp_ns, u64::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_control_variants_serialize() {
|
||||
let messages = vec![
|
||||
|
||||
Reference in New Issue
Block a user