//! 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::>() ); }