From af96bb341481cc5ca715e033f6219f9561385e12 Mon Sep 17 00:00:00 2001 From: Gavin Gray <20209337+gavinleroy@users.noreply.github.com> Date: Wed, 27 Nov 2024 17:22:23 -0500 Subject: [PATCH] Testing Infrastructure (#47) * Update the evaluation framework to use Nix. Run Fmt and Fix. Restructure the Makefile * Update evaluation scripts --- .gitignore | 1 + Makefile.toml | 83 +++++- crates/argus-cli/tests/test_examples.rs | 27 +- crates/argus/src/aadebug/mod.rs | 6 +- crates/argus/src/aadebug/tree.rs | 14 + crates/argus/src/ext.rs | 4 +- crates/argus/src/proof_tree/serialize.rs | 34 +-- flake.lock | 77 ++++- flake.nix | 39 ++- ide/packages/common/src/TreeInfo.ts | 67 +++-- ide/packages/common/src/context.ts | 13 +- ide/packages/common/src/lib.ts | 5 +- ide/packages/evaluation/package.json | 4 +- ide/packages/evaluation/src/basic.ts | 19 +- ide/packages/evaluation/src/main.ts | 35 ++- ide/packages/evaluation/src/page.ts | 7 +- ide/packages/evaluation/src/random.ts | 95 ------- ide/packages/evaluation/src/rootCauses.ts | 5 +- ide/packages/evaluation/src/utils.ts | 18 +- ide/packages/evaluation/src/visual.ts | 2 +- ide/packages/panoptes/src/App.tsx | 6 +- .../panoptes/src/TreeView/BottomUp.tsx | 47 +-- .../panoptes/src/TreeView/Erotisi.tsx | 6 +- .../panoptes/src/TreeView/TreeApp.tsx | 2 +- .../panoptes/src/TreeView/heuristic.ts | 268 ------------------ ide/pnpm-lock.yaml | 26 +- 26 files changed, 363 insertions(+), 547 deletions(-) delete mode 100644 ide/packages/evaluation/src/random.ts delete mode 100644 ide/packages/panoptes/src/TreeView/heuristic.ts diff --git a/.gitignore b/.gitignore index 2edd08e..ab1e14e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ bindings/ # Evaluation cache data/ +*.csv diff --git a/Makefile.toml b/Makefile.toml index 189b7ca..69ee2cc 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -2,27 +2,84 @@ skip_core_tasks = true default_to_workspace = false -[tasks.watch-front] -script = "cargo watch -i frontend -x 'install --path crates/argus-cli'" +# #################### # +# Binding initializers # +# #################### # -[tasks.watch-front-debug] -script = "cargo watch -i frontend -x 'install --path crates/argus-cli --frozen --offline --debug'" +[tasks.init-bindings-lib] +command = "cargo" +args = [ + "test", "-p", "argus-lib", "--lib", "export_bindings", "--locked" +] -[tasks.watch.run_task] -name = ["watch-front"] -parallel = true +[tasks.init-bindings-ser] +command = "cargo" +args = ["test", "-p", "argus-ser", "--locked"] [tasks.init-bindings] +command = "./scripts/ts-rs.scm" +dependences = ["tasks.init-bindings-lib", "tasks.init-bindings-ser"] + +[tasks.evaluation-node] +command = "node" +args = ["ide/packages/evaluation/dist/evaluation.cjs", "-s", "./data", "${@}"] + +# #################### # +# Builders # +# #################### # + +[tasks.build-back] +command = "cargo" +args = [ + "install", "--path", "crates/argus-cli", "--locked", +] + +# TODO: is there a way to set a command specific environment variable? +# The below will make the configuration global... +# [env] +# CARGO_MAKE_WORKING_DIRECTORY = "ide" +[tasks.build-ide] script = """ -cargo test -p argus-lib --lib export_bindings --locked -cargo test -p argus-ser --locked -./scripts/ts-rs.scm +cd ide && depot build """ -[tasks.evaluation] +[tasks.build.run_task] +name = ["build-back", "build-ide"] +parallel = true + +[tasks.watch-back] +command = "cargo" +args = [ + "watch", + "-i", + "frontend", + "-x", + "'install", "--path", "crates/argus-cli", "${@}", "'", +] + +[tasks.watch.run_task] +name = ["watch-back"] +parallel = true + +# ############### # +# Evaluation Crap # +# ############### # + +[tasks.eval] +command = "node" +args = ["ide/packages/evaluation/dist/evaluation.cjs", "-h", "${@}"] +dependencies = ["build"] + +[tasks.eval-init] +command = "node" +args = ["ide/packages/evaluation/dist/evaluation.cjs", "-s", "./data", "${@}"] +dependencies = ["build"] + +[tasks.eval-serve] script = """ -cd ide && depot build && cd .. -node ide/packages/evaluation/dist/evaluation.cjs -s ./data python3 -m webbrowser http://localhost:8080/eval ./scripts/evaluation.scm """ + +[tasks.evaluation] +dependencies = ["evaluation-init", "evaluation-serve"] diff --git a/crates/argus-cli/tests/test_examples.rs b/crates/argus-cli/tests/test_examples.rs index f070b17..1dcdb72 100644 --- a/crates/argus-cli/tests/test_examples.rs +++ b/crates/argus-cli/tests/test_examples.rs @@ -1,9 +1,16 @@ -use std::{env, fs, path::Path, process::Command, sync::Once}; +use std::{ + env, fs, + path::Path, + process::{Command, Stdio}, + sync::Once, +}; use anyhow::{ensure, Context, Result}; static SETUP: Once = Once::new(); +static DNF_PERF_P: &str = "dnf-perf.csv"; + fn run>(dir: P, f: impl FnOnce(&mut Command)) -> Result { let root = env::temp_dir().join("argus"); let heredir = Path::new(".").canonicalize()?; @@ -17,12 +24,13 @@ fn run>(dir: P, f: impl FnOnce(&mut Command)) -> Result { if !status.success() { panic!("installing argus failed") } + + fs::write(DNF_PERF_P, "Label,N,Time\n").unwrap(); }); let mut cmd = Command::new("cargo"); cmd.arg("argus"); - cmd.arg("obligations"); - // Don't specify a file to analyze all local crates. + cmd.arg("bundle"); let path = format!( "{}:{}", @@ -34,6 +42,14 @@ fn run>(dir: P, f: impl FnOnce(&mut Command)) -> Result { let ws = heredir.join("tests").join(dir); cmd.current_dir(&ws); + // NOTE: performance data is written to STDERR, so we capture it and place it in a file. + let perf_file = fs::OpenOptions::new() + .create(true) + .append(true) + .open(DNF_PERF_P) + .unwrap(); + cmd.stderr(Stdio::from(perf_file)); + f(&mut cmd); let _ = fs::remove_dir_all(ws.join("target")); @@ -61,13 +77,12 @@ macro_rules! mk_tests_for { mk_tests_for! { axum, bevy, - // chumsky, // NOTE: as of now this consumes too much memory + // chumsky, diesel, - easy_ml, + // easy_ml, entrait, nalgebra, uom - // tauri_project } // TODO: include individual test if we want to see a particular output diff --git a/crates/argus/src/aadebug/mod.rs b/crates/argus/src/aadebug/mod.rs index 3b69702..64d6fe5 100644 --- a/crates/argus/src/aadebug/mod.rs +++ b/crates/argus/src/aadebug/mod.rs @@ -18,6 +18,7 @@ use crate::proof_tree::{topology::TreeTopology, ProofNodeIdx}; pub struct Storage<'tcx> { pub ns: IndexVec>, maybe_ambiguous: bool, + report_performance: bool, } #[derive(Serialize, Debug, Clone)] @@ -30,9 +31,11 @@ pub struct AnalysisResults { impl<'tcx> Storage<'tcx> { pub fn new(maybe_ambiguous: bool) -> Self { + let report_performance = std::env::var("ARGUS_DNF_PERF").is_ok(); Self { ns: IndexVec::new(), maybe_ambiguous, + report_performance, } } @@ -106,7 +109,8 @@ impl<'tcx> Storage<'tcx> { root: ProofNodeIdx, topo: &TreeTopology, ) -> AnalysisResults { - let tree = &tree::T::new(root, &self.ns, topo, false); + let tree = + &tree::T::new(root, &self.ns, topo, false, self.report_performance); let tree_start = Instant::now(); let mut sets = vec![]; diff --git a/crates/argus/src/aadebug/tree.rs b/crates/argus/src/aadebug/tree.rs index fb6d1f9..0aeaba0 100644 --- a/crates/argus/src/aadebug/tree.rs +++ b/crates/argus/src/aadebug/tree.rs @@ -333,6 +333,7 @@ pub struct T<'a, 'tcx: 'a> { pub ns: &'a IndexVec>, pub topology: &'a TreeTopology, pub maybe_ambiguous: bool, + report_performance: bool, dnf: RefCell>>, } @@ -342,12 +343,14 @@ impl<'a, 'tcx: 'a> T<'a, 'tcx> { ns: &'a IndexVec>, topology: &'a TreeTopology, maybe_ambiguous: bool, + report_performance: bool, ) -> Self { Self { root, ns, topology, maybe_ambiguous, + report_performance, dnf: RefCell::new(None), } } @@ -436,8 +439,19 @@ impl<'a, 'tcx: 'a> T<'a, 'tcx> { let root = self.goal(self.root).expect("invalid root"); let dnf = _goal(self, &root).unwrap_or_else(Dnf::default); + timer::elapsed(&dnf_report_msg, dnf_start); + // HACK to gather the performance report we write to stderr the CSV values `PERF