//! Preparation only. Compile as an ordinary binary, never with --test. #[allow(dead_code)] #[path = "inputs/document.rs"] mod document; use document::Document; use oa_core::{Command, Id, Project, language, prepare_command, source_files}; use oa_core::source_project::{self, ProjectLimits, SourceBundle}; use oa_core::validation::Severity; use serde_json::{Value, json}; use std::collections::{BTreeMap, BTreeSet}; use std::path::{Path, PathBuf}; use std::time::Instant; const OLD: &str = "oa_restore_work"; const NEW: &str = "oa_restore_pressure"; fn timed(phase: &str, iteration: usize, action: impl FnOnce() -> T) -> T { let clock = Instant::now(); let result = action(); let elapsed = clock.elapsed(); // Printing, result checks and dropping returned values are outside the interval. println!("{}", json!({"record":"timing", "phase":phase, "iteration":iteration, "elapsed_ns":elapsed.as_nanos().to_string(), "seconds":elapsed.as_secs_f64()})); result } fn disk_files(root: &Path, here: &Path, files: &mut BTreeMap>) { for entry in std::fs::read_dir(here).expect("read fixture directory") { let entry = entry.expect("directory entry"); let kind = entry.file_type().expect("file kind"); assert!(!kind.is_symlink(), "fixture links are not allowed"); if kind.is_dir() { disk_files(root, &entry.path(), files); } else { assert!(kind.is_file()); files.insert(entry.path().strip_prefix(root).unwrap().to_owned(), std::fs::read(entry.path()).expect("read fixture bytes")); } } } fn physical(root: &Path) -> BTreeMap> { let mut result = BTreeMap::new(); disk_files(root, root, &mut result); result } fn ids(project: &Project) -> BTreeSet { project.identities().into_iter().map(|(id, _)| id).collect() } fn expected_source(baseline: &SourceBundle, cli: &Value) -> SourceBundle { assert_eq!(cli["format_version"], 1); assert_eq!(cli["operation"], "rename-alias"); assert_eq!(cli["status"], "preview"); assert_eq!(cli["exit_code"], 0); assert_eq!(cli["written"], false); let mut expected = baseline.clone(); let mut paths = BTreeSet::new(); let changes = cli["changes"].as_array().expect("preserved CLI changes"); assert!(!changes.is_empty()); for change in changes { let path = change["path"].as_str().expect("changed path"); assert!(paths.insert(path)); assert_eq!(baseline.files.get(path).map(String::as_str), change["before"].as_str()); *expected.files.get_mut(path).expect("existing source only") = change["after"].as_str().expect("expected source").to_owned(); } expected } fn main() { let args: Vec<_> = std::env::args().collect(); assert_eq!(args.len(), 4, "probe ENTRY CLI_PREVIEW_JSON ITERATIONS"); let entry = Path::new(&args[1]); let iterations: usize = args[3].parse().expect("iteration count"); assert!((1..=5).contains(&iterations), "bounded to 1..5 samples"); let root = entry.parent().expect("entry parent"); let before_disk = physical(root); assert_eq!(before_disk.len(), 37, "pinned realistic walkthrough"); let cli: Value = serde_json::from_slice(&std::fs::read(&args[2]).expect("CLI prediction")).unwrap(); let limits = ProjectLimits::default(); // Disk discovery/load is reported separately and excluded from accepted-command timing. let loaded = timed("source_files_load_including_io", 0, || source_files::load_project(entry, limits).expect("load fixture")); assert!(!loaded.diagnostics.iter().any(|d| d.diagnostic.severity == Severity::Error)); let baseline = loaded.reachable_bundle(); assert_eq!(baseline.files.len(), 30, "pinned reachable source count"); for source in baseline.files.values() { let declarations = language::analyze(source).declarations; assert!(declarations.iter().all(|declaration| declaration.id.is_some()), "all baseline declarations must retain authored identities"); } let expected_bundle = expected_source(&baseline, &cli); println!("{}", json!({"record":"fixture", "reachable_files":baseline.files.len(), "physical_files":before_disk.len(), "source_bytes":baseline.files.values().map(String::len).sum::(), "old":OLD,"new":NEW,"iterations":iterations, "scope":"accepted snapshot in-process, realistic release1; no UI/disk writes/RSS measurement"})); for iteration in 1..=iterations { // Cloning inputs is outside the initialization timing. Initialization remains separate. let initial = baseline.clone(); let mut document = timed("document_initial_compile_and_history_estimate", iteration, || Document::from_bundle(initial, limits).expect("initialize accepted document")); assert_eq!(document.bundle(), &baseline, "no UUID stabilization or normalization"); assert!(!document.dirty() && !document.can_undo() && !document.can_redo()); let original = document.project().clone(); let all_ids = ids(&original); let target = original.identities().into_iter().find(|(_, alias)| *alias == OLD).unwrap().0; assert!(!original.identities().iter().any(|(_, alias)| *alias == NEW)); let mut expected_project = original.clone(); expected_project.elements.get_mut(&target).expect("activity target").alias = NEW.into(); let snapshot = document.snapshot(); // Report the phase order: samples alternate to expose warm-up/order effects. let execute_first = iteration % 2 == 1; println!("{}",json!({"record":"order","iteration":iteration,"execute_first":execute_first})); if execute_first { let command = Command::SetAlias(target, NEW.into()); timed("document_execute", iteration, || document.execute(command)).expect("execute rename"); } let command = Command::SetAlias(target, NEW.into()); let prepared = timed("prepare_command", iteration, || prepare_command(&original, &command)).expect("prepare rename"); assert_eq!(prepared.project, expected_project); assert_eq!(ids(&prepared.project), all_ids); let updated = timed("source_update_with_identity_map", iteration, || source_project::update_bundle_with_identity_map(&snapshot, &prepared.project, &prepared.identity_map, limits)).expect("prepare source preview"); assert_eq!(updated.decoded.project, expected_project); assert_eq!(updated.bundle, expected_bundle, "full source equality to preserved CLI prediction"); assert_eq!(snapshot.bundle, baseline, "preview leaves accepted snapshot untouched"); assert_eq!(snapshot.decoded.project, original); if !execute_first { assert_eq!(document.project(), &original); assert_eq!(document.bundle(), &baseline); assert_eq!(document.revision(), 0); let command = Command::SetAlias(target, NEW.into()); timed("document_execute", iteration, || document.execute(command)).expect("execute rename"); } assert_eq!(document.project(), &expected_project); assert_eq!(document.bundle(), &expected_bundle); assert_eq!(ids(document.project()), all_ids); assert_eq!(document.revision(), 1); assert!(document.dirty() && document.can_undo() && !document.can_redo()); assert!(timed("document_undo", iteration, || document.undo())); assert_eq!(document.project(), &original); assert_eq!(document.bundle(), &baseline); assert_eq!(document.revision(), 2); assert!(!document.dirty() && !document.can_undo() && document.can_redo()); assert!(timed("document_redo", iteration, || document.redo())); assert_eq!(document.project(), &expected_project); assert_eq!(document.bundle(), &expected_bundle); assert_eq!(ids(document.project()), all_ids); assert_eq!(document.revision(), 3); assert!(document.dirty() && document.can_undo() && !document.can_redo()); // All file reads, equality assertions and output are outside command intervals. assert_eq!(physical(root), before_disk, "probe must not write fixture files"); println!("{}", json!({"record":"verified","iteration":iteration, "complete_project_source_equality":true,"uuid_set_unchanged":true, "preview_snapshot_unchanged":true,"undo_redo_exact":true,"physical_files_unchanged":true})); } assert_eq!(physical(root), before_disk); println!("{}",json!({"record":"complete","samples":iterations,"physical_files_unchanged":true})); }