rojo/tests/tests/build.rs
Joe 1ffed1212d Add prefetch cache for VFS to optimize file reads
- Introduced a `PrefetchCache` structure to store pre-read file contents and canonical paths, enhancing the speed of initial reads during snapshot building.
- Implemented parallel file reading using `rayon` and `walkdir` to populate the cache efficiently.
- Updated the `VfsInner` struct to include the prefetch cache and modified read methods to utilize it, reducing I/O operations.
- Added functions to set and clear the prefetch cache in the `Vfs` API, improving memory management during live operations.
- Enhanced tests to validate the functionality of the prefetch cache, ensuring correct behavior during file reads and canonicalization.

These changes aim to significantly improve the performance of the VFS by minimizing file access times during initial operations.
2026-02-19 02:04:15 -06:00

157 lines
4.2 KiB
Rust

use std::{fs, path::Path, process::Command};
use insta::assert_snapshot;
use tempfile::tempdir;
use crate::rojo_test::io_util::{get_working_dir_path, BUILD_TESTS_PATH, ROJO_PATH};
macro_rules! gen_build_tests {
( $($test_name: ident,)* ) => {
$(
paste::item! {
#[test]
fn [<build_ $test_name>]() {
let _ = env_logger::try_init();
run_build_test(stringify!($test_name));
}
}
)*
};
}
gen_build_tests! {
init_csv_with_children,
attributes,
client_in_folder,
client_init,
csv_bug_145,
csv_bug_147,
csv_in_folder,
deep_nesting,
gitkeep,
ignore_glob_inner,
ignore_glob_nested,
ignore_glob_spec,
infer_service_name,
infer_starter_player,
init_meta_class_name,
init_meta_properties,
init_with_children,
issue_546,
json_as_lua,
json_model_in_folder,
json_model_legacy_name,
module_in_folder,
module_init,
optional,
project_composed_default,
project_composed_file,
project_root_name,
rbxm_in_folder,
rbxmx_in_folder,
rbxmx_ref,
script_meta_disabled,
server_in_folder,
server_init,
txt,
txt_in_folder,
unresolved_values,
weldconstraint,
sync_rule_alone,
sync_rule_complex,
sync_rule_nested_projects,
no_name_default_project,
no_name_project,
no_name_top_level_project,
tilde_no_meta,
meta_name_override,
model_json_name_override,
dedup_suffix_with_meta,
dedup_suffix_auto_strip,
init_meta_name_override,
reserved_name_override,
}
fn run_build_test(test_name: &str) {
let working_dir = get_working_dir_path();
let input_path = Path::new(BUILD_TESTS_PATH).join(test_name);
let output_dir = tempdir().expect("couldn't create temporary directory");
let output_path = output_dir.path().join(format!("{}.rbxmx", test_name));
let output = Command::new(ROJO_PATH)
.args([
"build",
input_path.to_str().unwrap(),
"-o",
output_path.to_str().unwrap(),
])
.env("RUST_LOG", "error")
.current_dir(working_dir)
.output()
.expect("Couldn't start Rojo");
print!("{}", String::from_utf8_lossy(&output.stdout));
eprint!("{}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success(), "Rojo did not exit successfully");
let contents = fs::read_to_string(&output_path).expect("Couldn't read output file");
let mut settings = insta::Settings::new();
let snapshot_path = Path::new(BUILD_TESTS_PATH)
.parent()
.unwrap()
.join("build-test-snapshots");
settings.set_snapshot_path(snapshot_path);
settings.bind(|| {
assert_snapshot!(test_name, contents);
});
}
#[test]
fn parallel_snapshot_determinism() {
use crate::rojo_test::io_util::SERVE_TESTS_PATH;
let _ = env_logger::try_init();
let fixture_path = Path::new(SERVE_TESTS_PATH).join("connected_scripts");
let vfs = memofs::Vfs::new_default();
let ctx = librojo::InstanceContext::default();
fn snapshot_debug(snap: &librojo::InstanceSnapshot) -> String {
fn recurse(snap: &librojo::InstanceSnapshot, depth: usize, out: &mut String) {
use std::fmt::Write;
let indent = " ".repeat(depth);
writeln!(out, "{}{} [{}]", indent, snap.name, snap.class_name).unwrap();
for child in &snap.children {
recurse(child, depth + 1, out);
}
}
let mut s = String::new();
recurse(snap, 0, &mut s);
s
}
let first = librojo::snapshot_from_vfs(&ctx, &vfs, &fixture_path)
.expect("snapshot failed")
.expect("snapshot returned None");
let baseline = snapshot_debug(&first);
for i in 1..5 {
let vfs = memofs::Vfs::new_default();
let snap = librojo::snapshot_from_vfs(&ctx, &vfs, &fixture_path)
.expect("snapshot failed")
.expect("snapshot returned None");
let current = snapshot_debug(&snap);
assert_eq!(
baseline, current,
"Parallel snapshot produced different child order on iteration {i}"
);
}
}