{"record":{"id":"8a8f96e4c28a01f6","repo":"stamparm/maltrail","slug":"create-worker-log-dir","errorCode":null,"errorMessage":"create worker log dir","messagePattern":"create worker log dir","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sensor/src/testkit.rs","lineNumber":301,"sourceCode":"}\n\nimpl Drop for Harness {\n    fn drop(&mut self) {\n        let _ = std::fs::remove_dir_all(&self.dir);\n    }\n}\n\n/// A `WorkerContext` wired to `registry.slots[id]`, for tests that need to drive the real\n/// `worker::run` rather than the packet path alone — worker lifecycle, exit classification and\n/// the liveness metrics all live in `run`, not in `process_packet`.\n///\n/// The temporary directory is deliberately leaked (tests are short-lived and the OS reclaims\n/// `TMPDIR`); a `Drop` guard would have to outlive the returned context.\npub fn worker_context(registry: &Arc<crate::metrics::Registry>, id: usize) -> crate::worker::WorkerContext {\n    let counter = COUNTER.fetch_add(1, Ordering::Relaxed);\n    let dir = std::env::temp_dir().join(format!(\"maltrail-worker-{}-{}\", std::process::id(), counter));\n    let log_dir = dir.join(\"logs\");\n    std::fs::create_dir_all(&log_dir).expect(\"create worker log dir\");\n    let trails_file = dir.join(\"trails.csv\");\n    std::fs::write(&trails_file, \"\").expect(\"write trails\");\n\n    let config_file = dir.join(\"worker.conf\");\n    std::fs::write(\n        &config_file,\n        format!(\n            \"MONITOR_INTERFACE any\\n\\\n             CAPTURE_BUFFER 1MB\\n\\\n             PROCESS_COUNT 1\\n\\\n             UPDATE_PERIOD 999999999\\n\\\n             DISABLE_CHECK_SUDO true\\n\\\n             USE_CONDENSED_STORAGE false\\n\\\n             USE_HEURISTICS false\\n\\\n             SENSOR_NAME harness\\n\\\n             LOG_DIR {}\\n\\\n             TRAILS_FILE {}\\n\",\n            log_dir.display(),","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/stamparm/maltrail/blob/77cfb06d7606506d101bbcec0786c77166c4255e/sensor/src/testkit.rs#L283-L319","documentation":"Panic from `.expect(\"create worker log dir\")` when `std::fs::create_dir_all` cannot create the per-worker temporary logs directory under `$TMPDIR/maltrail-worker-<pid>-<n>`. The worker context needs this directory for LOG_DIR before any worker can run.","triggerScenarios":"`worker_context()` invoked while the temp filesystem is unwritable or full, the computed temp path collides with an existing non-directory file, or the OS temp dir is unwritable (permissions, read-only mount, sandboxed test runner).","commonSituations":"CI runners with restricted TMPDIR; TMPDIR pointing to a non-writable path; leftover file at the same path after a prior crashed run; disk-full container.","solutions":["Check that std::env::temp_dir() is writable and has free space in the failing environment","Remove any non-directory file occupying the target path","Clear stale maltrail-worker-* leftovers in TMPDIR","Run tests with TMPDIR set to a known-writable directory"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let log_dir = dir.join(\"logs\");\nassert!(std::env::temp_dir().is_dir(), \"TMPDIR does not exist\");\nstd::fs::create_dir_all(&log_dir).unwrap_or_else(|e| panic!(\"create worker log dir {}: {e}\", log_dir.display()));","typeGuard":null,"tryCatchPattern":"match std::fs::create_dir_all(&log_dir) {\n    Ok(_) => {},\n    Err(e) => panic!(\"create worker log dir {}: {e}\", log_dir.display()),\n}","preventionTips":["Set TMPDIR to a writable directory in CI containers","Clean stale maltrail-worker-* paths before test runs","Monitor temp filesystem free space"],"tags":["rust","filesystem","test-harness","tempdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"77cfb06d7606506d101bbcec0786c77166c4255e","analyzedAt":"2026-09-13T03:50:16.010Z","contentChangedAt":"2026-09-13T03:50:16.010Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}