|
| 1 | +#![no_main] |
| 2 | + |
| 3 | +use arbitrary::{Arbitrary, Unstructured}; |
| 4 | +use libfuzzer_sys::fuzz_target; |
| 5 | +use rustworkx_core::centrality::closeness_centrality; |
| 6 | +use rustworkx_core::petgraph::graph::UnGraph; |
| 7 | + |
| 8 | +#[derive(Debug, Arbitrary)] |
| 9 | +struct CentralityFuzzInput { |
| 10 | + edges: Vec<(usize, usize)>, |
| 11 | + node_count: usize, |
| 12 | +} |
| 13 | + |
| 14 | +macro_rules! assert_almost_equal { |
| 15 | + ($x:expr, $y:expr, $d:expr, $i:expr, $wf:expr) => { |
| 16 | + if ($x - $y).abs() >= $d { |
| 17 | + panic!( |
| 18 | + "{} != {} within delta of {} at node {} with wf_improved = {}", |
| 19 | + $x, $y, $d, $i, $wf |
| 20 | + ); |
| 21 | + } |
| 22 | + }; |
| 23 | +} |
| 24 | + |
| 25 | +fuzz_target!(|data: &[u8]| { |
| 26 | + if let Ok(input) = CentralityFuzzInput::arbitrary(&mut Unstructured::new(data)) { |
| 27 | + fuzz_centrality(input); |
| 28 | + } |
| 29 | +}); |
| 30 | + |
| 31 | +fn fuzz_centrality(input: CentralityFuzzInput) { |
| 32 | + if input.node_count == 0 || input.node_count > 1000 { |
| 33 | + return; |
| 34 | + } |
| 35 | + |
| 36 | + let mut graph = UnGraph::<(), ()>::default(); |
| 37 | + let nodes: Vec<_> = (0..input.node_count).map(|_| graph.add_node(())).collect(); |
| 38 | + |
| 39 | + for (u, v) in input.edges { |
| 40 | + if u < input.node_count && v < input.node_count { |
| 41 | + graph.add_edge(nodes[u], nodes[v], ()); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + let epsilon = 1e-4; |
| 46 | + |
| 47 | + for &wf_improved in &[true, false] { |
| 48 | + let seq_output = closeness_centrality(&graph, wf_improved, 200); |
| 49 | + let par_output = closeness_centrality(&graph, wf_improved, 1); |
| 50 | + |
| 51 | + let c_seq: Vec<f64> = seq_output.iter().map(|x| x.unwrap()).collect(); |
| 52 | + let c_par: Vec<f64> = par_output.iter().map(|x| x.unwrap()).collect(); |
| 53 | + |
| 54 | + assert_eq!(c_seq.len(), c_par.len(), "Centrality result size mismatch"); |
| 55 | + |
| 56 | + for (i, (a, b)) in c_seq.iter().zip(c_par.iter()).enumerate() { |
| 57 | + assert_almost_equal!(a, b, epsilon, i, wf_improved); |
| 58 | + } |
| 59 | + } |
| 60 | +} |
0 commit comments