Skip to content

Commit 487c1f6

Browse files
Adding Fuzz targets for random graph generator (#1430)
* Adding Fuzz targets for random graph generator Added a fuzz target for random graph generator with max edges. * Updates based on comments Added another test to check determinism (if same graph is returned for the same seed). * fixing lint issues * Removing unused imports --------- Co-authored-by: Ivan Carvalho <[email protected]>
1 parent ab84b60 commit 487c1f6

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

rustworkx-core/fuzz/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ path = "fuzz_targets/test_fuzz_bellman_ford.rs"
3434
test = false
3535
doc = false
3636
bench = false
37+
38+
[[bin]]
39+
name = "test_fuzz_random_graph"
40+
path = "fuzz_targets/test_fuzz_random_graph.rs"
41+
test = false
42+
doc = false
43+
bench = false
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![no_main]
2+
3+
use arbitrary::{Arbitrary, Unstructured};
4+
use libfuzzer_sys::fuzz_target;
5+
use rustworkx_core::generators::gnm_random_graph;
6+
use rustworkx_core::petgraph::graph::DiGraph;
7+
use rustworkx_core::petgraph::visit::EdgeRef;
8+
9+
#[derive(Debug, Arbitrary)]
10+
struct GnmInput {
11+
n: usize,
12+
m: usize,
13+
seed: Option<u64>,
14+
}
15+
16+
fuzz_target!(|data: &[u8]| {
17+
if let Ok(input) = GnmInput::arbitrary(&mut Unstructured::new(data)) {
18+
fuzz_gnm_random_graph(input);
19+
}
20+
});
21+
22+
fn fuzz_gnm_random_graph(input: GnmInput) {
23+
if input.n > 512 || input.m > 512 * 512 {
24+
return;
25+
}
26+
27+
let max_m = input.n.saturating_mul(input.n.saturating_sub(1));
28+
let capped_m = input.m.min(max_m);
29+
30+
if let Ok(graph1) = gnm_random_graph::<DiGraph<(), ()>, _, _, _, ()>(
31+
input.n,
32+
capped_m,
33+
input.seed,
34+
|| (),
35+
|| (),
36+
) {
37+
assert_eq!(graph1.node_count(), input.n);
38+
assert!(
39+
graph1.edge_count() <= max_m,
40+
"edge_count {} > max_m {}",
41+
graph1.edge_count(),
42+
max_m
43+
);
44+
45+
if input.seed.is_some() {
46+
if let Ok(graph2) = gnm_random_graph::<DiGraph<(), ()>, _, _, _, ()>(
47+
input.n,
48+
capped_m,
49+
input.seed,
50+
|| (),
51+
|| (),
52+
) {
53+
assert_eq!(graph1.node_count(), graph2.node_count());
54+
assert_eq!(graph1.edge_count(), graph2.edge_count());
55+
56+
let mut edges1: Vec<_> = graph1
57+
.edge_references()
58+
.map(|e| (e.source().index(), e.target().index()))
59+
.collect();
60+
let mut edges2: Vec<_> = graph2
61+
.edge_references()
62+
.map(|e| (e.source().index(), e.target().index()))
63+
.collect();
64+
65+
edges1.sort_unstable();
66+
edges2.sort_unstable();
67+
assert_eq!(edges1, edges2, "Graphs differ even with the same seed");
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)