Files
yvgude--lean-ctx/rust/tests/critical_module_integration.rs
wehub-resource-sync 26382a7ac6
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
JetBrains Plugin / Actionlint (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (rust) (push) Waiting to run
JetBrains Plugin / Validation (push) Waiting to run
JetBrains Plugin / Build (push) Waiting to run
JetBrains Plugin / Test (push) Blocked by required conditions
Security Check / Security Scan (push) Waiting to run
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
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

178 lines
5.4 KiB
Rust

// Integration tests for modules identified as critical during the architecture audit.
// Covers: pathjail, degradation_policy, gotcha_tracker/learn, cache CCR.
// ---------------------------------------------------------------------------
// pathjail: security-critical path containment
// ---------------------------------------------------------------------------
#[cfg(not(feature = "no-jail"))]
#[test]
fn pathjail_blocks_traversal() {
use lean_ctx::core::pathjail;
let jail = std::env::current_dir().unwrap();
let escaped = jail.join("../../etc/passwd");
let result = pathjail::jail_path(&escaped, &jail);
assert!(
result.is_err(),
"traversal path must be rejected by jail_path"
);
}
#[test]
fn pathjail_allows_safe_path() {
use lean_ctx::core::pathjail;
let jail = std::env::current_dir().unwrap();
let safe = jail.join("src/main.rs");
let result = pathjail::jail_path(&safe, &jail);
assert!(result.is_ok(), "path inside jail must be allowed");
}
// ---------------------------------------------------------------------------
// degradation_policy: must evaluate without panic
// ---------------------------------------------------------------------------
#[test]
fn degradation_policy_evaluates_for_known_tool() {
use lean_ctx::core::degradation_policy::evaluate_v1_for_tool;
let policy = evaluate_v1_for_tool("ctx_read", Some("2025-01-01T00:00:00Z"));
assert_eq!(policy.schema_version, 1);
assert_eq!(policy.tool, "ctx_read");
assert!(!policy.decision.reason.is_empty());
}
#[test]
fn degradation_policy_evaluates_for_unknown_tool() {
let policy = lean_ctx::core::degradation_policy::evaluate_v1_for_tool(
"nonexistent_tool",
Some("2025-01-01T00:00:00Z"),
);
assert_eq!(policy.tool, "nonexistent_tool");
}
// ---------------------------------------------------------------------------
// gotcha_tracker/learn: extract learnings from resolved gotchas
// ---------------------------------------------------------------------------
#[test]
fn learn_extracts_high_confidence_gotchas() {
use lean_ctx::core::gotcha_tracker::learn::extract_learnings;
use lean_ctx::core::gotcha_tracker::{
Gotcha, GotchaCategory, GotchaSeverity, GotchaSource, GotchaStats, GotchaStore,
};
let mut g = Gotcha::new(
GotchaCategory::Build,
GotchaSeverity::Warning,
"cargo build fails with missing feature",
"Add --all-features flag",
GotchaSource::AutoDetected {
command: "cargo build".into(),
exit_code: 1,
},
"sess-1",
);
g.confidence = 0.8;
g.occurrences = 3;
g.session_ids = vec!["a".into(), "b".into(), "c".into()];
let store = GotchaStore {
project_hash: "test".into(),
gotchas: vec![g],
error_log: vec![],
stats: GotchaStats::default(),
updated_at: chrono::Utc::now(),
pending_errors: vec![],
};
let learnings = extract_learnings(&store);
assert_eq!(learnings.len(), 1);
assert!(learnings[0].resolution.contains("--all-features"));
}
#[test]
fn learn_filters_low_confidence() {
use lean_ctx::core::gotcha_tracker::learn::extract_learnings;
use lean_ctx::core::gotcha_tracker::*;
let mut g = Gotcha::new(
GotchaCategory::Build,
GotchaSeverity::Info,
"some flaky thing",
"retry",
GotchaSource::AutoDetected {
command: "make".into(),
exit_code: 1,
},
"sess-1",
);
g.confidence = 0.3;
g.occurrences = 1;
let store = GotchaStore {
project_hash: "test".into(),
gotchas: vec![g],
error_log: vec![],
stats: GotchaStats::default(),
updated_at: chrono::Utc::now(),
pending_errors: vec![],
};
let learnings = extract_learnings(&store);
assert!(
learnings.is_empty(),
"low confidence gotchas should be filtered"
);
}
#[test]
fn learn_format_agents_section_has_markers() {
use lean_ctx::core::gotcha_tracker::learn::{Learning, format_agents_section};
let learnings = vec![Learning {
category: "build".into(),
trigger: "missing dep".into(),
resolution: "add to Cargo.toml".into(),
confidence: 0.9,
occurrences: 5,
sessions: 3,
}];
let section = format_agents_section(&learnings);
assert!(section.contains("lean-ctx-learn-start"));
assert!(section.contains("lean-ctx-learn-end"));
assert!(section.contains("missing dep"));
}
#[test]
fn learn_format_empty_returns_empty() {
use lean_ctx::core::gotcha_tracker::learn::format_agents_section;
let section = format_agents_section(&[]);
assert!(section.is_empty());
}
// ---------------------------------------------------------------------------
// cache CCR: get_full_content
// ---------------------------------------------------------------------------
#[test]
fn cache_get_full_content_returns_stored_content() {
use lean_ctx::core::cache::SessionCache;
let mut cache = SessionCache::new();
cache.store("/test/file.rs", "fn main() {}");
let content = cache.get_full_content("/test/file.rs");
assert!(content.is_some());
assert!(content.unwrap().contains("fn main"));
}
#[test]
fn cache_get_full_content_returns_none_for_missing() {
use lean_ctx::core::cache::SessionCache;
let cache = SessionCache::new();
let missing = cache.get_full_content("/nonexistent.rs");
assert!(missing.is_none());
}