From 67083c6dde22be9b08d420f349f99d891fee67cb Mon Sep 17 00:00:00 2001 From: HexLab98 Date: Thu, 30 Jul 2026 17:57:13 +0700 Subject: [PATCH] test(installer): pin own-pid adopt for desktop-prewritten update marker Regression for #74761: acquire must succeed when the marker already names this process (desktop writeUpdateMarker raced ahead), and still clean up on Drop. --- .../src-tauri/src/update.rs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/apps/bootstrap-installer/src-tauri/src/update.rs b/apps/bootstrap-installer/src-tauri/src/update.rs index 9aa77b53bc7..4614bacf1cb 100644 --- a/apps/bootstrap-installer/src-tauri/src/update.rs +++ b/apps/bootstrap-installer/src-tauri/src/update.rs @@ -1381,6 +1381,43 @@ mod tests { let _ = std::fs::remove_dir_all(&dir); } + #[test] + fn acquire_adopts_a_marker_prewritten_with_our_own_pid() { + // #74761: desktop writeUpdateMarker(hermesHome, child.pid) races ahead + // of UpdateMarkerGuard::acquire. The marker names US; refusing it made + // every in-app desktop update loop forever. Adopt and rewrite. + let dir = unique_tmp_dir("marker-own-pid"); + std::fs::create_dir_all(&dir).unwrap(); + let marker = dir.join(".hermes-update-in-progress"); + + let started_at = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_secs()) + .unwrap_or(0) + .saturating_sub(2); + std::fs::write(&marker, format!("{}\n{started_at}", std::process::id())).unwrap(); + + let guard = UpdateMarkerGuard::acquire(marker.clone()).unwrap_or_else(|owner| { + panic!( + "own-pid pre-write must be adoptable, got foreign owner pid={}", + owner.pid + ) + }); + assert!(marker.exists(), "adopted guard must own the marker"); + let body = std::fs::read_to_string(&marker).unwrap(); + assert_eq!( + body.lines().next().unwrap().trim().parse::().unwrap(), + std::process::id(), + "acquire rewrites the marker with our pid + fresh started_at" + ); + drop(guard); + assert!( + !marker.exists(), + "Drop must still clear the marker we adopted" + ); + let _ = std::fs::remove_dir_all(&dir); + } + #[test] fn acquire_reclaims_a_marker_owned_by_a_dead_pid() { let dir = unique_tmp_dir("marker-dead-pid");