Skip to content

Commit e483531

Browse files
authored
feat: let nargo test use the new greybox fuzzer (#8234)
1 parent 1ba0bfd commit e483531

13 files changed

Lines changed: 327 additions & 282 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/noirc_frontend/src/hir/def_map/mod.rs

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ impl CrateDefMap {
206206
match attributes.function().map(|attr| &attr.kind) {
207207
Some(FunctionAttributeKind::Test(scope)) => {
208208
let location = interner.function_meta(&func_id).name.location;
209-
Some(TestFunction::new(func_id, scope.clone(), location, has_arguments))
209+
let scope = scope.clone();
210+
Some(TestFunction { id: func_id, scope, location, has_arguments })
210211
}
211212
_ => None,
212213
}
@@ -230,7 +231,7 @@ impl CrateDefMap {
230231
match attributes.function().map(|attr| &attr.kind) {
231232
Some(FunctionAttributeKind::FuzzingHarness(scope)) => {
232233
let location = interner.function_meta(&func_id).name.location;
233-
Some(FuzzingHarness::new(func_id, scope.clone(), location))
234+
Some(FuzzingHarness { id: func_id, scope: scope.clone(), location })
234235
}
235236
_ => None,
236237
}
@@ -373,30 +374,13 @@ pub fn parse_file(fm: &FileManager, file_id: FileId) -> (ParsedModule, Vec<Parse
373374
}
374375

375376
pub struct TestFunction {
376-
id: FuncId,
377-
scope: TestScope,
378-
location: Location,
379-
has_arguments: bool,
377+
pub id: FuncId,
378+
pub scope: TestScope,
379+
pub location: Location,
380+
pub has_arguments: bool,
380381
}
381382

382383
impl TestFunction {
383-
fn new(id: FuncId, scope: TestScope, location: Location, has_arguments: bool) -> Self {
384-
TestFunction { id, scope, location, has_arguments }
385-
}
386-
387-
/// Returns the function id of the test function
388-
pub fn get_id(&self) -> FuncId {
389-
self.id
390-
}
391-
392-
pub fn file_id(&self) -> FileId {
393-
self.location.file
394-
}
395-
396-
pub fn has_arguments(&self) -> bool {
397-
self.has_arguments
398-
}
399-
400384
/// Returns true if the test function has been specified to fail
401385
/// This is done by annotating the function with `#[test(should_fail)]`
402386
/// or `#[test(should_fail_with = "reason")]`
@@ -418,25 +402,12 @@ impl TestFunction {
418402
}
419403

420404
pub struct FuzzingHarness {
421-
id: FuncId,
422-
scope: FuzzingScope,
423-
location: Location,
405+
pub id: FuncId,
406+
pub scope: FuzzingScope,
407+
pub location: Location,
424408
}
425409

426410
impl FuzzingHarness {
427-
fn new(id: FuncId, scope: FuzzingScope, location: Location) -> Self {
428-
FuzzingHarness { id, scope, location }
429-
}
430-
431-
/// Returns the function id of the test function
432-
pub fn get_id(&self) -> FuncId {
433-
self.id
434-
}
435-
436-
pub fn file_id(&self) -> FileId {
437-
self.location.file
438-
}
439-
440411
/// Returns true if the fuzzing harness has been specified to fail only under specific reason
441412
/// This is done by annotating the function with
442413
/// `#[fuzz(only_fail_with = "reason")]`

compiler/noirc_frontend/src/hir/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ impl Context<'_, '_> {
180180
.get_all_test_functions(interner)
181181
.filter_map(|test_function| {
182182
let fully_qualified_name =
183-
self.fully_qualified_function_name(crate_id, &test_function.get_id());
183+
self.fully_qualified_function_name(crate_id, &test_function.id);
184184
match &pattern {
185185
FunctionNameMatch::Anything => Some((fully_qualified_name, test_function)),
186186
FunctionNameMatch::Exact(patterns) => patterns
@@ -211,7 +211,7 @@ impl Context<'_, '_> {
211211
.get_all_fuzzing_harnesses(interner)
212212
.filter_map(|fuzzing_harness| {
213213
let fully_qualified_name =
214-
self.fully_qualified_function_name(crate_id, &fuzzing_harness.get_id());
214+
self.fully_qualified_function_name(crate_id, &fuzzing_harness.id);
215215
match &pattern {
216216
FunctionNameMatch::Anything => Some((fully_qualified_name, fuzzing_harness)),
217217
FunctionNameMatch::Exact(patterns) => patterns

tooling/greybox_fuzzer/src/lib.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ pub struct FuzzedExecutorExecutionConfiguration {
271271
pub num_threads: usize,
272272
/// Maximum time in seconds to spend fuzzing (default: no timeout)
273273
pub timeout: u64,
274+
/// Whether to output progress to stdout or not.
275+
pub show_progress: bool,
274276
}
275277

276278
pub enum FuzzedExecutorFailureConfiguration {
@@ -321,6 +323,9 @@ pub struct FuzzedExecutor<E, F> {
321323
/// Number of threads to use
322324
num_threads: usize,
323325

326+
/// Whether to output progress to stdout or not.
327+
show_progress: bool,
328+
324329
/// Determines what is considered a failure during execution
325330
failure_configuration: FuzzedExecutorFailureConfiguration,
326331

@@ -391,6 +396,7 @@ impl<
391396
package_name: package_name.to_string(),
392397
function_name: function_name.to_string(),
393398
num_threads: fuzz_execution_config.num_threads,
399+
show_progress: fuzz_execution_config.show_progress,
394400
failure_configuration,
395401
corpus_dir: PathBuf::from(
396402
folder_configuration.corpus_dir.unwrap_or(DEFAULT_CORPUS_FOLDER.to_string()),
@@ -530,17 +536,19 @@ impl<
530536
minimized_corpus_path =
531537
minimized_corpus.as_ref().unwrap().get_corpus_storage_path().to_path_buf();
532538
}
533-
let _ = display_starting_info(
534-
self.minimize_corpus,
535-
seed,
536-
starting_corpus_ids.len(),
537-
self.num_threads,
538-
&self.package_name,
539-
&self.function_name,
540-
corpus.get_corpus_storage_path(),
541-
&minimized_corpus_path,
542-
abi_change_detected,
543-
);
539+
if self.show_progress {
540+
let _ = display_starting_info(
541+
self.minimize_corpus,
542+
seed,
543+
starting_corpus_ids.len(),
544+
self.num_threads,
545+
&self.package_name,
546+
&self.function_name,
547+
corpus.get_corpus_storage_path(),
548+
&minimized_corpus_path,
549+
abi_change_detected,
550+
);
551+
}
544552

545553
// Generate the default input (it is needed if the corpus is empty)
546554
let default_map = self.mutator.generate_default_input_map();
@@ -745,7 +753,9 @@ impl<
745753
all_fuzzing_results.iter().find(|fast_result| fast_result.failed())
746754
{
747755
self.metrics.set_active_corpus_size(corpus.get_testcase_count());
748-
let _ = display_metrics(&self.metrics);
756+
if self.show_progress {
757+
let _ = display_metrics(&self.metrics);
758+
}
749759
break individual_failing_result.outcome().clone();
750760
}
751761

@@ -934,7 +944,9 @@ impl<
934944
// If we've found something, return
935945
if let Some(result) = failing_result {
936946
self.metrics.set_active_corpus_size(corpus.get_testcase_count());
937-
let _ = display_metrics(&self.metrics);
947+
if self.show_progress {
948+
let _ = display_metrics(&self.metrics);
949+
}
938950
break result;
939951
}
940952
if time_tracker.elapsed() - last_metric_check
@@ -943,7 +955,9 @@ impl<
943955
// Update and display metrics
944956
self.metrics.set_active_corpus_size(corpus.get_testcase_count());
945957
self.metrics.set_last_round_update_time(updating_time);
946-
let _ = display_metrics(&self.metrics);
958+
if self.show_progress {
959+
let _ = display_metrics(&self.metrics);
960+
}
947961
self.metrics.refresh_round();
948962
last_metric_check = time_tracker.elapsed();
949963
// Check if we've exceeded the timeout

tooling/lsp/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ fn get_package_tests_in_crate(
225225
let package_tests: Vec<_> = tests
226226
.into_iter()
227227
.map(|(func_name, test_function)| {
228-
let location = context.function_meta(&test_function.get_id()).name.location;
228+
let location = context.function_meta(&test_function.id).name.location;
229229
let file_id = location.file;
230230
let file_path = fm.path(file_id).expect("file must exist to contain tests");
231231
let range =

tooling/lsp/src/requests/code_lens_request.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub(crate) fn collect_lenses_for_package(
100100
let tests =
101101
context.get_all_test_functions_in_crate_matching(&crate_id, &FunctionNameMatch::Anything);
102102
for (func_name, test_function) in tests {
103-
let location = context.function_meta(&test_function.get_id()).name.location;
103+
let location = context.function_meta(&test_function.id).name.location;
104104
let file_id = location.file;
105105

106106
// Ignore diagnostics for any file that wasn't the file we saved

tooling/nargo/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ tracing.workspace = true
2828
serde.workspace = true
2929
serde_json.workspace = true
3030
walkdir = "2.5.0"
31-
noir_fuzzer = { workspace = true }
32-
proptest = { workspace = true }
3331
noir_greybox_fuzzer = { workspace = true }
3432

3533
# Some dependencies are optional so we can compile to Wasm.

tooling/nargo/src/ops/debug.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,8 @@ pub fn get_test_function_for_debug(
5858
}
5959
};
6060

61-
let test_function_has_arguments = !context
62-
.def_interner
63-
.function_meta(&test_function.get_id())
64-
.function_signature()
65-
.0
66-
.is_empty();
61+
let test_function_has_arguments =
62+
!context.def_interner.function_meta(&test_function.id).function_signature().0.is_empty();
6763

6864
if test_function_has_arguments {
6965
return Err(String::from("Cannot debug tests with arguments"));
@@ -78,7 +74,7 @@ pub fn compile_test_fn_for_debugging(
7874
compile_options: CompileOptions,
7975
) -> Result<CompiledProgram, noirc_driver::CompileError> {
8076
let compiled_program =
81-
compile_no_check(context, &compile_options, test_def.function.get_id(), None, false)?;
77+
compile_no_check(context, &compile_options, test_def.function.id, None, false)?;
8278
let expression_width =
8379
get_target_width(package.expression_width, compile_options.expression_width);
8480
let compiled_program = transform_program(compiled_program, expression_width);

0 commit comments

Comments
 (0)