#honggfuzz #fuzzing #proc-macro #testing

rutenspitz_macro

一个用于测试/模糊测试有状态模型与语义等效但显然正确的实现的过程宏

1 个不稳定版本

0.2.1 2020年7月28日

#83#fuzzing


用于 rutenspitz

MIT 许可证

21KB
460

rutenspitz

注意: 这个包之前被称作 arbitrary-model-tests.

Build status crates.io License: MIT

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

这个包受到了以下作品的启发

示例

参考 HashMap 测试

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

cargo hfuzz run hash_map

领域特定语言 (DSL)

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

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 {
        if op_name == "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