dag: add a fuzz test about range algorithm

Summary:
The test runs the old and new algorithm and compares their result.  This is more
interesting than using random numbers, since the fuzzing framework will try to
explore new code paths.

Reviewed By: sfilipco

Differential Revision: D19511576

fbshipit-source-id: e9a2066769b54a60bb92643e5715f91a6fccbcb5
This commit is contained in:
Jun Wu 2020-01-23 17:56:49 -08:00 committed by Facebook Github Bot
parent 78ea96cb9d
commit 494bdae7cc
5 changed files with 115 additions and 0 deletions

View File

@ -29,3 +29,15 @@ path = "fuzz_targets/gca.rs"
[[bin]]
name = "gca_small"
path = "fuzz_targets/gca_small.rs"
[[bin]]
name = "range"
path = "fuzz_targets/range.rs"
[[bin]]
name = "range_medium"
path = "fuzz_targets/range_medium.rs"
[[bin]]
name = "range_small"
path = "fuzz_targets/range_small.rs"

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#![no_main]
use bindag::TestContext;
use lazy_static::lazy_static;
use libfuzzer_sys::fuzz_target;
mod tests;
lazy_static! {
// The complete DAG is too large for `range` operation to run reasonably fast.
// Therefore take a subset of it.
static ref CONTEXT: TestContext = TestContext::from_bin_sliced(bindag::GIT, 49040..60415);
}
fuzz_target!(|input: (Vec<u16>, Vec<u16>)| {
let roots = CONTEXT.clamp_revs(&input.0);
let heads = CONTEXT.clamp_revs(&input.1);
tests::test_range(&CONTEXT, roots, heads);
});

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#![no_main]
use bindag::TestContext;
use lazy_static::lazy_static;
use libfuzzer_sys::fuzz_target;
mod tests;
lazy_static! {
// Pick a subset of the DAG (with many merges).
static ref CONTEXT: TestContext = TestContext::from_bin_sliced(bindag::GIT, 56666..60415);
}
fuzz_target!(|input: (Vec<u16>, Vec<u16>)| {
let roots = CONTEXT.clamp_revs(&input.0);
let heads = CONTEXT.clamp_revs(&input.1);
tests::test_range(&CONTEXT, roots, heads);
});

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#![no_main]
use bindag::TestContext;
use lazy_static::lazy_static;
use libfuzzer_sys::fuzz_target;
mod tests;
lazy_static! {
static ref CONTEXT: TestContext = {
let start = 60146;
TestContext::from_bin_sliced(bindag::GIT, start..start + 256)
};
}
fuzz_target!(|input: (Vec<u8>, Vec<u8>)| {
let roots = CONTEXT.clamp_revs(&input.0);
let heads = CONTEXT.clamp_revs(&input.1);
tests::test_range(&CONTEXT, roots, heads);
});

View File

@ -19,3 +19,28 @@ pub fn test_gca(context: &TestContext, namedag_revs: Vec<usize>) {
namedag_gca.sort_unstable();
assert_eq!(plain_gca, namedag_gca, "gca({:?})", &plain_revs);
}
#[allow(dead_code)]
pub fn test_range(context: &TestContext, roots: Vec<usize>, heads: Vec<usize>) {
let plain_roots: Vec<_> = roots.iter().map(|&i| context.idmap[i]).collect();
let plain_heads: Vec<_> = heads.iter().map(|&i| context.idmap[i]).collect();
let mut plain_range = bindag::range(&context.parents, &plain_roots, &plain_heads);
plain_range.sort_unstable();
let namedag_roots = SpanSet::from_spans(roots.iter().map(|&i| Id(i as u64)));
let namedag_heads = SpanSet::from_spans(heads.iter().map(|&i| Id(i as u64)));
let mut namedag_range = context.to_plain_revs(
&context
.id_dag()
.range(namedag_roots, namedag_heads)
.expect("IdDag::range"),
);
namedag_range.sort_unstable();
assert_eq!(
plain_range, namedag_range,
"range({:?}::{:?})",
&roots, &heads
);
}