File size: 4,382 Bytes
ea39c0e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | use pretty_assertions::assert_eq;
use serde_json::json;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;
use super::EncodedFrame;
use super::FramedReader;
use super::FramedWriter;
use super::MAX_FRAME_BYTES;
#[test]
fn complete_frame_round_trips_without_a_byte_stream() {
let value = json!({"type": "session/open", "sessionId": "session-1"});
let bytes = EncodedFrame::encode(&value)
.expect("encode frame")
.into_framed_bytes();
assert_eq!(
EncodedFrame::decode_framed::<serde_json::Value>(&bytes).expect("decode frame"),
value
);
}
#[test]
fn complete_frame_rejects_truncated_and_trailing_payloads() {
let value = json!({"value": 1});
let bytes = EncodedFrame::encode(&value)
.expect("encode frame")
.into_framed_bytes();
let truncated = &bytes[..bytes.len() - 1];
let truncated_error = EncodedFrame::decode_framed::<serde_json::Value>(truncated)
.expect_err("truncated frame should fail");
assert_eq!(truncated_error.kind(), std::io::ErrorKind::InvalidData);
let mut trailing = bytes;
trailing.push(0);
let trailing_error = EncodedFrame::decode_framed::<serde_json::Value>(&trailing)
.expect_err("frame with trailing bytes should fail");
assert_eq!(trailing_error.kind(), std::io::ErrorKind::InvalidData);
}
#[tokio::test]
async fn frame_wire_format_is_little_endian_length_prefixed_json() {
let (writer, mut reader) = tokio::io::duplex(/*max_buf_size*/ 128);
let write = tokio::spawn(async move {
FramedWriter::new(writer)
.write(&json!({"value": 1}))
.await
.expect("write frame");
});
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await.expect("read bytes");
write.await.expect("writer task");
let payload = br#"{"value":1}"#;
let mut expected = (payload.len() as u32).to_le_bytes().to_vec();
expected.extend_from_slice(payload);
assert_eq!(bytes, expected);
}
#[tokio::test]
async fn fragmented_frame_round_trips() {
let value = json!({"type": "session/open", "sessionId": "session-1"});
let payload = serde_json::to_vec(&value).expect("serialize");
let mut bytes = (payload.len() as u32).to_le_bytes().to_vec();
bytes.extend(payload);
let (mut writer, reader) = tokio::io::duplex(/*max_buf_size*/ 128);
let write = tokio::spawn(async move {
for byte in bytes {
writer.write_all(&[byte]).await.expect("write byte");
tokio::task::yield_now().await;
}
});
assert_eq!(
FramedReader::new(reader)
.read::<serde_json::Value>()
.await
.expect("read frame"),
Some(value)
);
write.await.expect("writer task");
}
#[tokio::test]
async fn eof_is_clean_only_at_a_frame_boundary() {
let (writer, reader) = tokio::io::duplex(/*max_buf_size*/ 16);
drop(writer);
assert_eq!(
FramedReader::new(reader)
.read::<serde_json::Value>()
.await
.expect("clean eof"),
None
);
let (mut writer, reader) = tokio::io::duplex(/*max_buf_size*/ 16);
writer
.write_all(&[1, 0])
.await
.expect("write partial header");
drop(writer);
let err = FramedReader::new(reader)
.read::<serde_json::Value>()
.await
.expect_err("truncated header");
assert_eq!(err.kind(), std::io::ErrorKind::UnexpectedEof);
}
#[tokio::test]
async fn oversized_and_malformed_frames_are_rejected() {
let (mut writer, reader) = tokio::io::duplex(/*max_buf_size*/ 16);
writer
.write_all(&((MAX_FRAME_BYTES as u32) + 1).to_le_bytes())
.await
.expect("write oversized header");
let err = FramedReader::new(reader)
.read::<serde_json::Value>()
.await
.expect_err("oversized frame");
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
let (mut writer, reader) = tokio::io::duplex(/*max_buf_size*/ 16);
writer
.write_all(&(1_u32).to_le_bytes())
.await
.expect("write length");
writer.write_all(b"{").await.expect("write malformed json");
let err = FramedReader::new(reader)
.read::<serde_json::Value>()
.await
.expect_err("malformed frame");
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
}
|