问题描述
我想测试我的一个应该恐慌的函数,但我的 GitHub 操作 abort()
导致即使我的代码要求“仅”2**31
字节(在我的实际代码中,限制是 { {1}}) 我的电脑有,GitHub 操作没有这样的内存 :p.
libc::c_int::MAX
但这失败了:
#[test]
#[should_panic]
fn reserve_with_max() {
Vec::with_capacity(usize::MAX);
}
这会停止测试并报告错误,即使这是我所期望的(恐慌或中止)。
我没有找到太多关于这个问题的信息:
- https://github.com/rust-lang/rust/issues/67650
- https://doc.rust-lang.org/std/alloc/fn.set_alloc_error_hook.html(但每晚)
我希望应该有一个 test tests::bad_fd ... ok
test tests::create_true ... ok
test tests::create_false ... ok
test tests::create_with_one ... ok
memory allocation of 25769803764 bytes Failed
,我该如何处理?
目前我显而易见的解决方案是#[should_abort]
测试:
ignore
解决方法
你可以分叉测试,但有很多缺点:
- 需要 nix(也许某处有一个与操作系统无关的 fork 板条箱......)
- 测试代码变得复杂
- 代码覆盖工具问题
- 询问更多资源
- 笨手笨脚的
#[test]
#[ignore = "Still ignored taupaulin doesn't like it too"]
fn create_with_max() {
use nix::{
sys::{
signal::Signal,wait::{waitpid,WaitStatus},},unistd::{fork,ForkResult},};
use std::panic;
use std::process::abort;
match unsafe { fork() } {
Ok(ForkResult::Parent { child }) => match waitpid(child,None) {
Ok(WaitStatus::Signaled(_,s,_)) => {
if s != Signal::SIGABRT {
panic!("Didn't abort")
}
}
o => panic!("Didn't expect: {:?}",o),Ok(ForkResult::Child) => {
let result = panic::catch_unwind(|| {
Vec::with_capacity(usize::MAX);
});
if let Err(_) = result {
abort();
}
}
Err(_) => panic!("Fork failed"),}
}
我不认为我会建议这样做。
,有一个 RFC 2116 允许配置 rust 来解决内存崩溃而不是 abort()
:
[profile.dev]
oom = "panic"
[profile.release]
oom = "panic"
缺点:
- 即使在每晚都没有实施#43596
- 它适用于您的用例,因为它是一个 oom 中止,但它不是测试中句柄
abort()
的通用解决方案。