Skip to content

Commit

Permalink
adapt dap iterface to debug test functions
Browse files Browse the repository at this point in the history
  • Loading branch information
anaPerezGhiglia committed Feb 27, 2025
1 parent a233ab3 commit 9947290
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 25 deletions.
14 changes: 10 additions & 4 deletions tooling/debugger/src/dap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::PathBuf;

use acvm::acir::native_types::WitnessMap;
use acvm::{BlackBoxFunctionSolver, FieldElement};
use bn254_blackbox_solver::Bn254BlackBoxSolver;
use nargo::PrintOutput;

use crate::context::DebugContext;
Expand Down Expand Up @@ -66,6 +67,7 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver<FieldElement>> DapSession<
initial_witness: WitnessMap<FieldElement>,
root_path: Option<PathBuf>,
package_name: String,
foreign_call_resolver_url: Option<String>,
) -> Self {
let context = DebugContext::new(
solver,
Expand All @@ -74,7 +76,7 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver<FieldElement>> DapSession<
initial_witness,
Box::new(DefaultDebugForeignCallExecutor::from_artifact(
PrintOutput::Stdout,
None, // TODO: set oracle_resolver url
foreign_call_resolver_url,
debug_artifact,
root_path,
package_name,
Expand Down Expand Up @@ -609,24 +611,28 @@ impl<'a, R: Read, W: Write, B: BlackBoxFunctionSolver<FieldElement>> DapSession<
}
}

pub fn run_session<R: Read, W: Write, B: BlackBoxFunctionSolver<FieldElement>>(
pub fn run_session<R: Read, W: Write>(
server: Server<R, W>,
solver: &B,
program: CompiledProgram,
initial_witness: WitnessMap<FieldElement>,
root_path: Option<PathBuf>,
package_name: String,
pedantic_solver: bool,
foreign_call_resolver_url: Option<String>,
) -> Result<(), ServerError> {
let debug_artifact =
DebugArtifact { debug_symbols: program.debug.clone(), file_map: program.file_map.clone() };

let solver = Bn254BlackBoxSolver(pedantic_solver);
let mut session = DapSession::new(
server,
solver,
&solver,
&program,
&debug_artifact,
initial_witness,
root_path,
package_name,
foreign_call_resolver_url,
);

session.run_loop()
Expand Down
9 changes: 5 additions & 4 deletions tooling/debugger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::path::PathBuf;
use ::dap::errors::ServerError;
use ::dap::server::Server;
use acvm::acir::native_types::{WitnessMap, WitnessStack};
use acvm::{BlackBoxFunctionSolver, FieldElement};
use acvm::FieldElement;

use nargo::NargoError;
use noirc_driver::CompiledProgram;
Expand All @@ -37,13 +37,14 @@ pub fn run_repl_session(
)
}

pub fn run_dap_loop<R: Read, W: Write, B: BlackBoxFunctionSolver<FieldElement>>(
pub fn run_dap_loop<R: Read, W: Write>(
server: Server<R, W>,
solver: &B,
program: CompiledProgram,
initial_witness: WitnessMap<FieldElement>,
root_path: Option<PathBuf>,
package_name: String,
pedantic_solving: bool,
foreign_call_resolver_url: Option<String>,
) -> Result<(), ServerError> {
dap::run_session(server, solver, program, initial_witness, root_path, package_name)
dap::run_session(server, program, initial_witness, root_path, package_name, pedantic_solving, foreign_call_resolver_url)
}
21 changes: 20 additions & 1 deletion tooling/lsp/src/requests/code_lens_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const EXECUTE_COMMAND: &str = "nargo.execute";
const EXECUTE_CODELENS_TITLE: &str = "Execute";
const DEBUG_COMMAND: &str = "nargo.debug.dap";
const DEBUG_CODELENS_TITLE: &str = "Debug";
const DEBUG_TEST_COMMAND: &str = "nargo.debug.test";
const DEBUG_TEST_CODELENS_TITLE: &str = "Debug test";

fn with_arrow(title: &str) -> String {
format!("{ARROW} {title}")
Expand Down Expand Up @@ -117,7 +119,7 @@ pub(crate) fn collect_lenses_for_package(
arguments: Some(
[
package_selection_args(workspace, package),
vec!["--exact".into(), "--show-output".into(), func_name.into()],
vec!["--exact".into(), "--show-output".into(), func_name.clone().into()],
]
.concat(),
),
Expand All @@ -126,6 +128,23 @@ pub(crate) fn collect_lenses_for_package(
let test_lens = CodeLens { range, command: Some(test_command), data: None };

lenses.push(test_lens);

let debug_test_command = Command {
title: DEBUG_TEST_CODELENS_TITLE.to_string(),
command: DEBUG_TEST_COMMAND.into(),
arguments: Some(
[
package_selection_args(workspace, package),
vec!["--exact".into(), func_name.into()],
]
.concat(),
),
};

let debug_test_lens = CodeLens { range, command: Some(debug_test_command), data: None };

lenses.push(debug_test_lens);

}

if package.is_binary() {
Expand Down
63 changes: 55 additions & 8 deletions tooling/nargo_cli/src/cli/dap_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use acvm::acir::circuit::ExpressionWidth;
use acvm::acir::native_types::WitnessMap;
use acvm::FieldElement;
use bn254_blackbox_solver::Bn254BlackBoxSolver;
use clap::Args;
use nargo::constants::PROVER_INPUT_FILE;
use nargo::package::Package;
use nargo::workspace::Workspace;
use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection};
use noirc_abi::input_parser::Format;
Expand All @@ -19,7 +19,8 @@ use dap::server::Server;
use dap::types::Capabilities;
use serde_json::Value;

use super::debug_cmd::{compile_bin_package_for_debugging, compile_options_for_debugging};
use super::check_cmd::check_crate_and_report_errors;
use super::debug_cmd::{compile_bin_package_for_debugging, compile_options_for_debugging, compile_test_fn_for_debugging, get_test_function, load_workspace_files, prepare_package_for_debug};
use super::fs::inputs::read_inputs_from_file;
use crate::errors::CliError;

Expand Down Expand Up @@ -49,6 +50,9 @@ pub(crate) struct DapCommand {
#[clap(long)]
preflight_skip_instrumentation: bool,

#[clap(long)]
preflight_test_name: Option<String>,

/// Use pedantic ACVM solving, i.e. double-check some black-box function
/// assumptions when solving.
/// This is disabled by default.
Expand Down Expand Up @@ -99,26 +103,59 @@ fn workspace_not_found_error_msg(project_folder: &str, package: Option<&str>) ->
}
}

fn compile_main(
workspace: &Workspace,
package: &Package,
expression_width: ExpressionWidth,
compile_options: &CompileOptions,
) -> Result<CompiledProgram, LoadError> {
compile_bin_package_for_debugging(&workspace, package, &compile_options, expression_width)
.map_err(|_| LoadError::Generic("Failed to compile project".into()))
}

fn compile_test(
workspace: &Workspace,
package: &Package,
expression_width: ExpressionWidth,
compile_options: CompileOptions,
test_name: String,
) -> Result<CompiledProgram, LoadError> {
let (file_manager, mut parsed_files) = load_workspace_files(&workspace);

let (mut context, crate_id) =
prepare_package_for_debug(&file_manager, &mut parsed_files, package, &workspace);

check_crate_and_report_errors(&mut context, crate_id, &compile_options).map_err(|_| LoadError::Generic("Failed to compile project".into()))?;

let test = get_test_function(crate_id, &context, &test_name).map_err(|_| LoadError::Generic("Failed to compile project".into()))?;

compile_test_fn_for_debugging(&test, &mut context, package, compile_options, Some(expression_width)).map_err(|_| LoadError::Generic("Failed to compile project".into()))

}

fn load_and_compile_project(
project_folder: &str,
package: Option<&str>,
prover_name: &str,
expression_width: ExpressionWidth,
acir_mode: bool,
skip_instrumentation: bool,
test_name: Option<String>,
) -> Result<(CompiledProgram, WitnessMap<FieldElement>, PathBuf, String), LoadError> {
let workspace = find_workspace(project_folder, package)
.ok_or(LoadError::Generic(workspace_not_found_error_msg(project_folder, package)))?;
let package = workspace
.into_iter()
.find(|p| p.is_binary())
.ok_or(LoadError::Generic("No matching binary packages found in workspace".into()))?;
.find(|p| p.is_binary() || p.is_contract())
.ok_or(LoadError::Generic("No matching binary or contract packages found in workspace. Only these packages can be debugged.".into()))?;

let compile_options =
compile_options_for_debugging(acir_mode, skip_instrumentation, CompileOptions::default());
let compiled_program =
compile_bin_package_for_debugging(&workspace, package, &compile_options, expression_width)
.map_err(|_| LoadError::Generic("Failed to compile project".into()))?;

let compiled_program = match test_name {
None => compile_main(&workspace, &package, expression_width, &compile_options),
Some(test_name) => compile_test(&workspace, &package, expression_width, compile_options, test_name),
}?;

let (inputs_map, _) =
read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &compiled_program.abi)
Expand Down Expand Up @@ -174,6 +211,12 @@ fn loop_uninitialized_dap<R: Read, W: Write>(
.get("skipInstrumentation")
.and_then(|v| v.as_bool())
.unwrap_or(generate_acir);
let test_name =
additional_data.get("testName").and_then(|v| v.as_str()).map(String::from);
let oracle_resolver_url = additional_data
.get("oracleResolver")
.and_then(|v| v.as_str())
.map(String::from);

eprintln!("Project folder: {}", project_folder);
eprintln!("Package: {}", package.unwrap_or("(default)"));
Expand All @@ -186,17 +229,19 @@ fn loop_uninitialized_dap<R: Read, W: Write>(
expression_width,
generate_acir,
skip_instrumentation,
test_name,
) {
Ok((compiled_program, initial_witness, root_path, package_name)) => {
server.respond(req.ack()?)?;

noir_debugger::run_dap_loop(
server,
&Bn254BlackBoxSolver(pedantic_solving),
compiled_program,
initial_witness,
Some(root_path),
package_name,
pedantic_solving,
oracle_resolver_url,
)?;
break;
}
Expand Down Expand Up @@ -231,6 +276,7 @@ fn run_preflight_check(
};

let package = args.preflight_package.as_deref();
let test_name = args.preflight_test_name;
let prover_name = args.preflight_prover_name.as_deref().unwrap_or(PROVER_INPUT_FILE);

let _ = load_and_compile_project(
Expand All @@ -240,6 +286,7 @@ fn run_preflight_check(
expression_width,
args.preflight_generate_acir,
args.preflight_skip_instrumentation,
test_name,
)?;

Ok(())
Expand Down
16 changes: 8 additions & 8 deletions tooling/nargo_cli/src/cli/debug_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ fn debug_test_fn(
compile_options: CompileOptions,
run_params: RunParams,
) -> TestResult {
let compiled_program = compile_test_fn_for_debugging(test, context, package, compile_options);
let compiled_program = compile_test_fn_for_debugging(test, context, package, compile_options, None);

let test_status = match compiled_program {
Ok(compiled_program) => {
Expand Down Expand Up @@ -199,16 +199,17 @@ fn debug_test_fn(
)
}

fn compile_test_fn_for_debugging(
pub(super) fn compile_test_fn_for_debugging(
test_def: &TestDefinition,
context: &mut Context,
package: &Package,
compile_options: CompileOptions,
expression_with: Option<ExpressionWidth>,
) -> Result<CompiledProgram, noirc_driver::CompileError> {
let compiled_program =
compile_no_check(context, &compile_options, test_def.function.get_id(), None, false)?;
let expression_width =
get_target_width(package.expression_width, compile_options.expression_width);
expression_with.unwrap_or(get_target_width(package.expression_width, compile_options.expression_width));
let compiled_program = nargo::ops::transform_program(compiled_program, expression_width);
Ok(compiled_program)
}
Expand Down Expand Up @@ -321,18 +322,17 @@ fn debug_test(
Ok(())
}

struct TestDefinition {
pub(super) struct TestDefinition {
name: String,
function: TestFunction,
}

// TODO: move to nargo::ops and reuse in test_cmd?
fn get_test_function(
pub(super) fn get_test_function(
crate_id: CrateId,
context: &Context,
test_name: &str,
) -> Result<TestDefinition, CliError> {
// TODO: review Contains signature and check if its ok to send test_name as single element
let test_pattern = FunctionNameMatch::Contains(vec![test_name.into()]);

let test_functions = context.get_all_test_functions_in_crate_matching(&crate_id, &test_pattern);
Expand Down Expand Up @@ -369,14 +369,14 @@ fn get_test_function(
Ok(TestDefinition { name: test_name, function: test_function })
}

fn load_workspace_files(workspace: &Workspace) -> (FileManager, ParsedFiles) {
pub(super) fn load_workspace_files(workspace: &Workspace) -> (FileManager, ParsedFiles) {
let mut file_manager = file_manager_with_stdlib(std::path::Path::new(""));
insert_all_files_for_workspace_into_file_manager(workspace, &mut file_manager);

let parsed_files = parse_all(&file_manager);
(file_manager, parsed_files)
}
pub(crate) fn prepare_package_for_debug<'a>(
pub(super) fn prepare_package_for_debug<'a>(
file_manager: &'a FileManager,
parsed_files: &'a mut ParsedFiles,
package: &'a Package,
Expand Down

0 comments on commit 9947290

Please sign in to comment.