#honggfuzz #fuzzing #proc-macro #testing

arbitrary-model-tests

这是一个过程宏,用于对有状态模型进行测试/模糊测试,测试目标实现语义上完全等价但明显正确的简单实现。

1个不稳定版本

0.1.0 2020年7月5日

1789过程宏

MIT 许可证

20KB
383

arbitrary-model-tests

Build status

这是一个尝试创建一个方便的过程宏,用于测试有状态模型(特别是各种数据结构)与简单(但通常非常低效)的实现进行对比,该实现语义上100%等价于目标实现,但明显是正确的。宏的目的是生成测试模型特定操作的样板代码,以便用户提供的测试定义尽可能简洁。

此Crate受到以下作品的启发

示例

参考HashMap测试

您可以使用cargo hfuzz运行它。首先,您需要安装honggfuzz及其系统依赖项。有关更多详细信息,请参阅本节。完成安装后,只需运行测试即可

cargo hfuzz run hash_map

DSL

这是描述要测试的有状态模型的DSL(在这个例子中是std::collections::HashMap)的初步尝试。

arbitrary_stateful_operations! {
    model = ModelHashMap<K, V>,
    tested = HashMap<K, V, BuildAHasher>,

    type_parameters = <
        K: Clone + Debug + Eq + Hash + Ord,
        V: Clone + Debug + Eq + Ord
    >,

    methods {
        equal {
            fn clear(&mut self);
            fn contains_key(&self, k: &K) -> bool;
            fn get(&self, k: &K) -> Option<&V>;
            fn get_key_value(&self, k: &K) -> Option<(&K, &V)>;
            fn get_mut(&mut self, k: &K) -> Option<&mut V>;
            fn insert(&mut self, k: K, v: V) -> Option<V>;
            // Tested as invariants, so no longer needed.
            // fn is_empty(&self) -> bool;
            // fn len(&self) -> usize;
            fn remove(&mut self, k: &K) -> Option<V>;
        }

        equal_with(sort_iterator) {
            fn drain(&mut self) -> impl Iterator<Item = (K, V)>;
            fn iter(&self) -> impl Iterator<Item = (&K, &V)>;
            fn iter_mut(&self) -> impl Iterator<Item = (&K, &mut V)>;
            fn keys(&self) -> impl Iterator<Item = &K>;
            fn values(&self) -> impl Iterator<Item = &V>;
            fn values_mut(&mut self) -> impl Iterator<Item = &mut V>;
        }
    }

    pre {
        let prev_capacity = tested.capacity();
    }

    post {
        // A bit of a hack.
        if &self == &Self::clear {
            assert_eq!(tested.capacity(), prev_capacity);
        }

        assert!(tested.capacity() >= model.len());
        assert_eq!(tested.is_empty(), model.is_empty());
        assert_eq!(tested.len(), model.len());
    }
}

依赖项

~1.5MB
~36K SLoC