Files
kebab/crates/kebab-config/tests/pdf_ocr.rs
altair823 bf7769cf5a refactor(config): env 97→~25 + 노출 키 109→~30 (표면 정리)
apply_env 의 KEBAB_* 매치 암을 103개→22개로 정리. 삭제된 암은 런타임에서
바꿀 일이 거의 없는 per-field 튜닝 노브(score_thresh, rrf_k, temperature,
multi_hop_*, nli_threshold, chunker_version, context_tokens 등) — struct
field 와 serde default 는 그대로 유지하므로 TOML 로는 여전히 설정 가능.

유지한 22개: endpoint×3, 모델명/프로바이더×5, 경로×2, 병렬도×2,
청킹 target/overlap×2, OCR 엔진/모델/언어+per-medium enabled×5,
caption enabled×1, search default_k×1, rag prompt_template_version×1.

영향 범위: struct field 삭제 없음(defaults 불변) → search/ask/chunk 출력
byte-identical 확인 (parity gate u2-surface IDENTICAL ✓).

docs: README KEBAB_* 항목을 실제 노출 키 목록으로 교체.
      SMOKE.md config 예시를 ~30개 공통 키로 슬림화 + env 설명 갱신.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Mc6W1fgsrbFKTsqA6P8La
2026-06-24 11:21:11 +00:00

96 lines
3.6 KiB
Rust

// crates/kebab-config/tests/pdf_ocr.rs
//
// Integration tests for [pdf.ocr] config section (v0.20.0 sub-item 1).
use kebab_config::{Config, PdfCfg};
use std::collections::HashMap;
// Test 1: toml roundtrip — spec §4.5 line 1034-1047 example block.
// Config requires many required fields; test the [pdf] section via PdfCfg wrapper.
#[derive(serde::Deserialize)]
struct PdfWrapper {
pdf: PdfCfg,
}
#[test]
fn pdf_ocr_toml_roundtrip() {
let toml = r#"
[pdf.ocr]
enabled = true
always_on = false
engine = "ollama-vision"
model = "qwen2.5vl:7b"
endpoint = "http://192.168.0.47:11434"
languages = ["eng", "kor"]
max_pixels = 3072
request_timeout_secs = 900
valid_ratio_threshold = 0.6
min_char_count = 30
lang_hint = "kor"
"#;
let w: PdfWrapper = toml::from_str(toml).expect("parse toml");
let ocr = &w.pdf.ocr;
assert!(ocr.enabled);
assert!(!ocr.always_on);
assert_eq!(ocr.engine, "ollama-vision");
assert_eq!(ocr.model, "qwen2.5vl:7b");
assert_eq!(ocr.endpoint.as_deref(), Some("http://192.168.0.47:11434"));
assert_eq!(ocr.languages, vec!["eng".to_string(), "kor".to_string()]);
assert_eq!(ocr.max_pixels, 3072);
assert_eq!(ocr.request_timeout_secs, 900);
assert!((ocr.valid_ratio_threshold - 0.6).abs() < 1e-6);
assert_eq!(ocr.min_char_count, 30);
assert_eq!(ocr.lang_hint.as_deref(), Some("kor"));
}
// Test 2: defaults — opt-in, qwen2.5vl:3b model, 0.5 threshold, 20 min_char.
#[test]
fn pdf_ocr_defaults_off_with_qwen_3b() {
let cfg = Config::defaults();
assert!(!cfg.ingest.pdf.ocr.enabled);
assert!(!cfg.ingest.pdf.ocr.always_on);
assert_eq!(cfg.ingest.pdf.ocr.engine, "ollama-vision");
assert_eq!(cfg.ingest.pdf.ocr.model, "qwen2.5vl:3b");
assert!(cfg.ingest.pdf.ocr.endpoint.is_none());
assert_eq!(
cfg.ingest.pdf.ocr.languages,
vec!["eng".to_string(), "kor".to_string()]
);
assert_eq!(cfg.ingest.pdf.ocr.max_pixels, 2048);
assert_eq!(cfg.ingest.pdf.ocr.request_timeout_secs, 180); // Bug #11: 600 → 60 → 180 (HOTFIXES 2026-05-28)
assert!((cfg.ingest.pdf.ocr.valid_ratio_threshold - 0.5).abs() < 1e-6);
assert_eq!(cfg.ingest.pdf.ocr.min_char_count, 20);
assert_eq!(cfg.ingest.pdf.ocr.lang_hint.as_deref(), Some("kor"));
}
// Test 3: env var override — pdf enabled + shared engine knob.
// v5: `model` moved to the shared `KEBAB_OCR_MODEL` (sets both mediums);
// `enabled` stays per-medium addressable.
// KEBAB_PDF_OCR_ALWAYS_ON and KEBAB_PDF_OCR_VALID_RATIO_THRESHOLD removed
// from env surface (config-only) in Unit 2 surface trim.
#[test]
fn pdf_ocr_env_overrides() {
let mut env: HashMap<String, String> = HashMap::new();
env.insert("KEBAB_PDF_OCR_ENABLED".to_string(), "true".to_string());
env.insert("KEBAB_OCR_MODEL".to_string(), "qwen2.5vl:7b".to_string());
// always_on and valid_ratio_threshold arms gone — silently ignored below.
env.insert("KEBAB_PDF_OCR_ALWAYS_ON".to_string(), "true".to_string());
env.insert(
"KEBAB_PDF_OCR_VALID_RATIO_THRESHOLD".to_string(),
"0.75".to_string(),
);
let cfg = Config::defaults().apply_env(&env);
assert!(cfg.ingest.pdf.ocr.enabled);
assert_eq!(cfg.ingest.pdf.ocr.model, "qwen2.5vl:7b");
// always_on arm gone — stays at default (false).
assert!(!cfg.ingest.pdf.ocr.always_on);
// valid_ratio_threshold arm gone — stays at default (0.5).
assert!((cfg.ingest.pdf.ocr.valid_ratio_threshold - 0.5).abs() < 1e-6);
// 다른 env var 가 default 보존
assert_eq!(cfg.ingest.pdf.ocr.engine, "ollama-vision");
assert_eq!(cfg.ingest.pdf.ocr.min_char_count, 20);
}