#read-write #partial #proptest #quickcheck #io-operations #tokio #async-io

dev partial-io

用于测试部分、中断和可能阻塞的I/O操作的辅助工具,支持通过proptest和quickcheck进行属性测试

7个版本

0.5.4 2022年9月28日
0.5.3 2022年9月27日
0.5.0 2021年1月28日
0.4.0 2020年9月25日
0.3.1 2019年6月7日

异步 中排名第87

Download history 1986/week @ 2024-03-14 1789/week @ 2024-03-21 1952/week @ 2024-03-28 2592/week @ 2024-04-04 1719/week @ 2024-04-11 1777/week @ 2024-04-18 2218/week @ 2024-04-25 1688/week @ 2024-05-02 2439/week @ 2024-05-09 1809/week @ 2024-05-16 1653/week @ 2024-05-23 1958/week @ 2024-05-30 1605/week @ 2024-06-06 1549/week @ 2024-06-13 2534/week @ 2024-06-20 1350/week @ 2024-06-27

每月下载量7,481
14 crates 中使用

MIT协议

67KB
1K SLoC

partial-io

partial-io on crates.io Documentation (latest release) Documentation (main) License

用于测试具有部分、中断和阻塞读写操作的I/O行为的辅助工具。

该库提供

  • PartialReadPartialWrite,这些是对现有的 ReadWrite 实现的包装,并允许在下一个 readwriteflush 调用上指定任意行为。
  • 通过可选的 futures03tokio1 功能,PartialAsyncReadPartialAsyncWrite 可用于包装现有的 AsyncReadAsyncWrite 实现。这些实现是任务感知的,因此如果它们返回一个 WouldBlock 错误,它们将知道如何暂停和恢复任务。
  • 通过可选的 proptest1 (proptest) 和 quickcheck1 (quickcheck) 功能,生成随机操作序列进行属性测试。有关更多信息,请参阅 proptest_typesquickcheck_types 文档。

动机

一个 ReadWrite 包装器在概念上很简单,但要正确实现它可能很困难,特别是如果包装器有一个内部缓冲区。常见问题包括

  • 即使是部分读取或写入,即使没有错误,也可能使包装器处于无效状态(示例修复)。

借助 futures03tokio1 提供的 AsyncReadAsyncWrite

  • 在包装器内部调用 read_to_endwrite_all 可能只部分成功,然后出错。这些函数将返回错误,而不告知调用者读取或写入了多少。具有内部缓冲区的包装器需要推进它们与部分成功相对应的状态,因此它们不能使用 read_to_endwrite_all示例修复)。
  • 实例必须向上传播 Poll::Pending,但这不应该使它们处于无效状态。

这些情况可能很难思考,也难以测试。

partial-io 可以从两个方面提供帮助

  1. 对于涉及这些情况中的任何情况的已知错误,partial-io 可以帮助您编写测试。
  2. 启用 quickcheck1 功能后,partial-io 还可以帮助在您的包装器中抖出错误。有关更多信息,请参阅 quickcheck_types

示例

use std::io::{self, Cursor, Read};

use partial_io::{PartialOp, PartialRead};

let data = b"Hello, world!".to_vec();
let cursor = Cursor::new(data);  // Cursor<Vec<u8>> implements io::Read
let ops = vec![PartialOp::Limited(7), PartialOp::Err(io::ErrorKind::Interrupted)];
let mut partial_read = PartialRead::new(cursor, ops);

let mut out = vec![0; 256];

// The first read will read 7 bytes.
assert_eq!(partial_read.read(&mut out).unwrap(), 7);
assert_eq!(&out[..7], b"Hello, ");
// The second read will fail with ErrorKind::Interrupted.
assert_eq!(partial_read.read(&mut out[7..]).unwrap_err().kind(), io::ErrorKind::Interrupted);
// The iterator has run out of operations, so it no longer truncates reads.
assert_eq!(partial_read.read(&mut out[7..]).unwrap(), 6);
assert_eq!(&out[..13], b"Hello, world!");

对于现实世界的示例,请参阅 zstd-rs 中的测试

最低支持的 Rust 版本

最低支持的 Rust 版本(MSRV)是 1.56

当软件包处于预发布状态(0.x.x)时,它可能在补丁版本中提高 MSRV。一旦软件包达到 1.x,任何 MSRV 的提升都将伴随着一个新的小版本。

贡献

有关如何帮助的信息,请参阅CONTRIBUTING 文件。

许可

此项目可在MIT 许可证下使用。

依赖项

~0–2MB
~34K SLoC