4个版本
0.1.3 | 2023年11月4日 |
---|---|
0.1.2 | 2023年1月28日 |
0.1.1 | 2022年7月11日 |
0.1.0 | 2022年4月3日 |
#134 in 测试
在circular-buffer中使用
85KB
944 行
Rust Drop Tracker
Rust crate用于检查变量是否被正确丢弃。此crate主要用于单元测试,涉及ManuallyDrop
、MaybeUninit
、不安全内存管理、自定义容器等。
具体来说,此crate允许您测试变量是否存活或已被丢弃,并检测变量是否被重复丢弃。这些功能可以用于检测自定义包装器或容器中的错误,这些错误使用了不安全内存管理且无法在编译时通过Rust编译器进行检查。
概念
此crate的主要结构是DropTracker
。初始化跟踪器后,您可以在上面调用DropTracker::track
以获取一个DropItem
。每个丢弃项都由一个键标识;可以在任何时候使用该键检查项的状态并查看它是否存活或已被丢弃。
示例
这是测试容器(如Vec
)在容器被丢弃时丢弃所有项的方法
use drop_tracker::DropTracker;
let mut tracker = DropTracker::new();
// Create a new vector and add a bunch of elements to it. The elements in this case are
// identified by integer keys (1, 2, 3), but any hashable type would work.
let v = vec![tracker.track(1),
tracker.track(2),
tracker.track(3)];
// Assert that all elements in the vector are alive
tracker.all_alive(1..=3)
.expect("expected all elements to be alive");
// Once the vector is dropped, all items should be dropped with it
drop(v);
tracker.all_dropped(1..=3)
.expect("expected all elements to be dropped");
这是测试涉及MaybeUninit
的结构的方法
use std::mem::MaybeUninit;
struct MyOption<T> {
set: bool,
data: MaybeUninit<T>,
}
impl<T> MyOption<T> {
fn none() -> Self {
Self { set: false, data: MaybeUninit::uninit() }
}
fn some(x: T) -> Self {
Self { set: true, data: MaybeUninit::new(x) }
}
}
// BUG: MyOption<T> does not implement Drop!
// BUG: The instance inside `data` may be initialized but not be properly destructed!
// BUG: The following code will silently leak memory:
let opt = MyOption::some(String::from("hello"));
drop(opt); // the String does not get deallocated
// DropTracker is able to catch this sort of bugs:
use drop_tracker::DropTracker;
let mut tracker = DropTracker::new();
let opt = MyOption::some(tracker.track("item"));
tracker.state(&"item")
.alive()
.expect("item is expected to be alive"); // works
drop(opt);
tracker.state(&"item")
.dropped()
.expect("item is expected to be dropped"); // panics, meaning that the bug was detected