diff --git a/Cargo.lock b/Cargo.lock index 35ff97f55e3..15ad7806a17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1510,6 +1510,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "file-lock" +version = "2.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "040b48f80a749da50292d0f47a1e2d5bf1d772f52836c07f64bfccc62ba6e664" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "filetime" version = "0.2.25" @@ -2777,6 +2787,7 @@ dependencies = [ "criterion", "dap", "dirs", + "file-lock", "fm", "iai", "iter-extended", diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index 317706bb237..02e669f5c68 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -78,6 +78,7 @@ dirs.workspace = true assert_cmd = "2.0.8" assert_fs = "1.0.10" predicates = "2.1.5" +file-lock = "2.1.11" fm.workspace = true criterion.workspace = true pprof.workspace = true diff --git a/tooling/nargo_cli/build.rs b/tooling/nargo_cli/build.rs index 984419fe388..a3b718b157d 100644 --- a/tooling/nargo_cli/build.rs +++ b/tooling/nargo_cli/build.rs @@ -168,7 +168,11 @@ fn generate_test_cases( } let test_cases = test_cases.join("\n"); - // Use a common mutex for all test cases. + // We need to isolate test cases in the same group, otherwise they overwrite each other's artifacts. + // On CI we use `cargo nextest`, which runs tests in different processes; for this we use a file lock. + // Locally we might be using `cargo test`, which run tests in the same process; in this case the file lock + // wouldn't work, becuase the process itself has the lock, and it looks like it can have N instances without + // any problems; for this reason we also use a `Mutex`. let mutex_name = format! {"TEST_MUTEX_{}", test_name.to_uppercase()}; write!( test_file, @@ -180,10 +184,16 @@ lazy_static::lazy_static! {{ {test_cases} fn test_{test_name}(force_brillig: bool, inliner_aggressiveness: i64) {{ + let test_program_dir = PathBuf::from("{test_dir}"); + // Ignore poisoning errors if some of the matrix cases failed. - let _guard = {mutex_name}.lock().unwrap_or_else(|e| e.into_inner()); + let mutex_guard = {mutex_name}.lock().unwrap_or_else(|e| e.into_inner()); - let test_program_dir = PathBuf::from("{test_dir}"); + let file_guard = file_lock::FileLock::lock( + test_program_dir.join("Nargo.toml"), + true, + file_lock::FileOptions::new().read(true).write(true).append(true) + ).expect("failed to lock Nargo.toml"); let mut nargo = Command::cargo_bin("nargo").unwrap(); nargo.arg("--program-dir").arg(test_program_dir); @@ -194,6 +204,9 @@ fn test_{test_name}(force_brillig: bool, inliner_aggressiveness: i64) {{ }} {test_content} + + drop(file_guard); + drop(mutex_guard); }} "# ) @@ -363,7 +376,7 @@ fn generate_compile_success_empty_tests(test_file: &mut File, test_data_dir: &Pa "info", &format!( r#" - nargo.arg("--json"); + nargo.arg("--json"); {assert_zero_opcodes} "#, ),