首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用不安全代码的rustdoc测试会失败,但是集成测试中相同的代码会通过呢?

为什么使用不安全代码的rustdoc测试会失败,但是集成测试中相同的代码会通过呢?
EN

Stack Overflow用户
提问于 2018-07-31 03:27:38
回答 1查看 371关注 0票数 0

我正在尝试编写一个名为insert的方法的rustdoc测试。测试函数在测试的最后一行中调用,当我注释掉它时,测试通过得很好。

错误消息:

代码语言:javascript
复制
$ cargo test
   Compiling reproduce v0.1.0 
(file:///home/user/reproduce)                                                           
    Finished dev [unoptimized + debuginfo] target(s) in 2.03s
     Running target/debug/deps/reproduce-17ad4bb50aa9c47e

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests reproduce

running 1 test
test src/lib.rs - MyStruct::method (line 19) ... FAILED

failures:

failures:
    src/lib.rs - MyStruct::method (line 19)

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--doc'

代码:

代码语言:javascript
复制
impl MyStruct {
    pub fn new(lsb: u8, step: usize) -> MyStruct {
        let mask: u8 = match lsb {
            1 => 0b0000_0001,
            2 => 0b0000_0011,
            _ => 0b0000_1111
        };

        MyStruct { lsb, mask, step }
    }

    /// # Examples
    /// ```
    /// extern crate reproduce;
    /// extern crate rgb;
    ///
    /// use std::slice;
    /// use rgb::RGB;
    ///
    /// let msg = "This is a secret message".as_bytes();
    /// let img = vec![RGB {r: 0, g: 0, b: 0}; 800*500];
    ///
    /// // Create a reference to the bytes of img
    /// let p: *const Vec<RGB<u8>> = &img;
    /// let p: *const u8 = p as *const u8;
    /// let p: &[u8] = unsafe { 
    ///     slice::from_raw_parts(p, 3*800*500)
    /// };
    ///
    /// let settings = reproduce::MyStruct::new(2, 12);
    /// let new_data = settings.method(p, &msg);
    /// ```
    pub fn method(&self, img: &[u8], msg: &[u8]) -> Vec<u8> {
        let mut ret = img.to_vec();
        let mut n = 0;

        for ch in msg.iter() {
            for i in 1..=8/self.lsb {
                let shift = (self.lsb*i) as u32;
                ret[n] = (ret[n] & !self.mask) |
                    (ch & self.mask.rotate_right(shift)).rotate_left(shift);
                n += self.step;
            }
        }

        ret
    }
}

是否有特定的规则可以让rustdoc测试通过(例如,使用assert!宏来证明它返回一个适当的值)?

我之所以问这个问题,是因为我的方法通过了与代码非常相似的集成测试,所以我很有信心它是正确的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-31 11:29:57

这与它在rustdoc测试中运行这一事实无关。您的代码表现出未定义的行为,因为它是不健全的。在测试之外运行相同的代码也会让我感到恐慌。

您正在对内存的布局进行假设--这些假设绝不会得到任何编译器保证的支持。获得指针的一种“正确”方法是:

代码语言:javascript
复制
let p = img.as_ptr() as *const u8;

然而,虽然这消除了关于Vec布局的假设,但其余的代码仍然假定RGB的布局。这一变化使我不再恐慌,但我不能确定它是否正常工作,而且我也不知道它是否会在其他计算机上发生故障,或者在下一次锈蚀更新之后在我的电脑上出现故障。

我之所以问这个问题,是因为我的方法通过了与代码非常相似的集成测试,所以我很有信心它是正确的

这正是未定义行为的危险所在,这也是为什么unsafe只应用于不仅经过良好测试的代码,而且也适用于对假设和保证有很好理解的代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51605046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档