Files
Lumotia/src-tauri/tests/tracing_appender_smoke.rs
Jake 27661c816e agent: lumotia — pin rust toolchain + workspace clippy/fmt sweep
rust-toolchain.toml pins to stable 1.94.1 so contributors and CI runners
share the exact rustc / rustfmt / clippy versions. Without the pin, every
machine surfaces a different lint set depending on its local install — six
pre-existing lints showed up on 1.94.1 that 1.93-era HANDOVER reported clean.

Clippy fixes (all pre-existing, not introduced by feature work):

- crates/storage/src/database.rs: std::iter::repeat().take() -> repeat_n()
- crates/llm/src/lib.rs (docs): "+ frontends" was parsed as a markdown bullet
  continuation by rustdoc, breaking doc-lazy-continuation. Reworded to "and".
- crates/llm/src/lib.rs (loop): while-let-on-iterator -> for-loop.
- src-tauri/src/commands/security.rs: .iter().any(|a| *a == x) -> .contains(&x).
- src-tauri/src/lib.rs: io::Error::new(Other, e) -> io::Error::other(e).
- src-tauri/src/tauri_app_data_migration.rs: drop function-tail `return`s
  inside cfg blocks; each platform's block now ends with a tail expression.

cargo fmt sweep across the workspace. Mechanical layout-only changes;
no semantics affected.

Workspace gates after this commit:
- cargo fmt --check: clean
- cargo clippy --workspace --all-targets -- -D warnings: clean
- cargo test --workspace: 405/0 (will become 409/0 with Phase A.1+A.2)
2026-05-14 07:19:59 +01:00

84 lines
3.3 KiB
Rust

//! Smoke test for the rolling-file tracing appender wired into
//! `init_tracing`. Pre-fix, `init_tracing` only installed an stderr
//! writer — meaning `lumotia.log` (referenced by the diagnostic-report
//! bundler and documented in `crates/storage/src/file_storage.rs`) was
//! never written and every user crash report shipped an empty log
//! attachment.
//!
//! This test asserts the post-fix behaviour: calling `install_subscriber`
//! against a tempdir creates the rolling log file and writes any
//! emitted `tracing::*!` lines to it after the worker thread drains.
//!
//! Notes:
//! - The non-blocking appender writes asynchronously. We force the
//! drain by dropping the returned `WorkerGuard` before reading the
//! file (the guard's drop blocks until the queue is empty).
//! - `tracing-subscriber`'s global dispatcher can only be initialised
//! once per process; integration tests each run in their own process
//! binary so this is safe.
//! - The default file-side `EnvFilter` includes `lumotia=debug` and
//! `lumotia_lib=debug`. We emit the test line with explicit target
//! `"lumotia_lib"` so the filter allows it through regardless of
//! where this test's module path lives.
use std::fs;
use std::thread::sleep;
use std::time::Duration;
use tempfile::tempdir;
#[test]
fn init_tracing_creates_log_file() {
let dir = tempdir().expect("create tempdir");
let logs_dir = dir.path().to_path_buf();
// Install the subscriber against the tempdir. The guard is returned
// so the test can deterministically flush by dropping it below.
let guard = lumotia_lib::install_subscriber(&logs_dir)
.expect("install_subscriber should succeed on a writable tempdir");
// Emit a known-unique marker. `target: "lumotia_lib"` matches the
// default file-side EnvFilter (`lumotia_lib=debug`).
tracing::info!(target: "lumotia_lib", "tracing_appender_smoke_marker_xyzzy");
// Drop the guard to flush the non-blocking worker queue. After this
// returns, any buffered log lines have been written to disk.
drop(guard);
// Belt-and-braces: a brief sleep in case the OS hasn't yet made
// the write visible to a subsequent read (unlikely on Linux, but
// cheap insurance for CI on macOS/Windows).
sleep(Duration::from_millis(50));
// Find any file matching `lumotia*log*` in the logs dir. The daily
// rotation policy means the live file is named like
// `lumotia.log.2026-05-12` (date suffix appended by the appender).
let entries: Vec<_> = fs::read_dir(&logs_dir)
.expect("read tempdir")
.filter_map(Result::ok)
.filter(|e| e.file_name().to_string_lossy().starts_with("lumotia"))
.collect();
assert!(
!entries.is_empty(),
"no lumotia*.log file was created in {}",
logs_dir.display()
);
// At least one of those files must contain the marker we emitted.
let mut found = false;
for entry in &entries {
let contents = fs::read_to_string(entry.path()).unwrap_or_default();
if contents.contains("tracing_appender_smoke_marker_xyzzy") {
found = true;
break;
}
}
assert!(
found,
"marker line not found in any of {:?}",
entries.iter().map(|e| e.path()).collect::<Vec<_>>()
);
}