#fuzzing #proc-macro #testing #honggfuzz #operation

rutenspitz

用于测试/模糊测试有状态模型(特别是各种数据结构)与语义上100%等效但显然正确的实现之间的过程宏

5 个不稳定版本

0.3.0 2022年3月12日
0.2.1 2020年7月28日
0.2.0 2020年7月21日
0.1.2 2020年7月20日
0.1.1 2020年7月20日

#fuzzing 中排名 50

MIT 许可证

8KB
65

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
~38K SLoC