Files
yvgude--lean-ctx/rust/tests/multi_read_cap_scenarios.rs
T
wehub-resource-sync 26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

102 lines
3.6 KiB
Rust

use std::sync::Mutex;
use lean_ctx::core::cache::SessionCache;
use lean_ctx::tools::CrpMode;
use lean_ctx::tools::ctx_multi_read;
/// `LCTX_MAX_MULTI_READ_BYTES` is process-global, so tests that mutate it must
/// not run concurrently or they clobber each other's value. Serialize them.
static ENV_GUARD: Mutex<()> = Mutex::new(());
fn setup_test_files(count: usize, size_per_file: usize) -> (tempfile::TempDir, Vec<String>) {
let dir = tempfile::tempdir().unwrap();
let mut paths = Vec::new();
for i in 0..count {
let path = dir.path().join(format!("file_{i}.txt"));
let content = format!("// File {i}\n{}", "x".repeat(size_per_file));
std::fs::write(&path, &content).unwrap();
paths.push(path.to_string_lossy().to_string());
}
(dir, paths)
}
#[test]
fn multi_read_respects_output_cap() {
let _guard = ENV_GUARD
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { std::env::set_var("LCTX_MAX_MULTI_READ_BYTES", "10000") };
let (_dir, paths) = setup_test_files(20, 5000);
let mut cache = SessionCache::new();
let output = ctx_multi_read::handle(&mut cache, &paths, "full", CrpMode::Off);
assert!(
output.contains("Output capped"),
"output must contain cap warning when exceeding limit:\n{}",
&output[output.len().saturating_sub(300)..]
);
assert!(
output.contains("file(s) skipped"),
"must report skipped files"
);
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { std::env::remove_var("LCTX_MAX_MULTI_READ_BYTES") };
}
#[test]
fn multi_read_no_cap_when_under_limit() {
let _guard = ENV_GUARD
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { std::env::set_var("LCTX_MAX_MULTI_READ_BYTES", "1000000") };
let (_dir, paths) = setup_test_files(3, 100);
let mut cache = SessionCache::new();
let output = ctx_multi_read::handle(&mut cache, &paths, "full", CrpMode::Off);
assert!(
!output.contains("Output capped"),
"should not cap when under limit"
);
assert!(output.contains("Read 3 files"), "should read all files");
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { std::env::remove_var("LCTX_MAX_MULTI_READ_BYTES") };
}
#[test]
fn multi_read_empty_paths() {
let _guard = ENV_GUARD
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let mut cache = SessionCache::new();
let output = ctx_multi_read::handle(&mut cache, &[], "full", CrpMode::Off);
assert!(output.contains("Read 0 files"));
}
#[test]
fn multi_read_single_large_file_passes() {
let _guard = ENV_GUARD
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { std::env::set_var("LCTX_MAX_MULTI_READ_BYTES", "100000") };
let (_dir, paths) = setup_test_files(1, 50000);
let mut cache = SessionCache::new();
let output = ctx_multi_read::handle(&mut cache, &paths, "full", CrpMode::Off);
assert!(
output.contains("Read 1 files"),
"single file should always be included even if large"
);
assert!(
!output.contains("Output capped"),
"single file should not trigger cap"
);
// TODO: Audit that the environment access only happens in single-threaded code.
unsafe { std::env::remove_var("LCTX_MAX_MULTI_READ_BYTES") };
}