Files
doctate/clients/desktop/tests/single_instance_lock_test.rs
Brummel 0c66fc6010 refactor: rename to common/, clients/desktop, clients/wearos
Move three directories into their target topology:
- doctate-common/ -> common/
- client-desktop/ -> clients/desktop/
- watch/wearos/   -> clients/wearos/

Update doctate-common path-dependency in 3 Cargo.toml files
(server, clients/desktop, experiments) and the workspace
members list in the root Cargo.toml. Crate names unchanged
(doctate-server, doctate-common, doctate-desktop).

Workspace still in single-Cargo.lock form; isolation into
standalone workspaces follows in stage 3. All 508 tests pass,
experiments standalone-workspace also resolves the new path.
2026-05-02 11:55:38 +02:00

50 lines
1.6 KiB
Rust

//! Regression guard for the single-instance lock in `main.rs`. The
//! implementation relies on `std::fs::File::try_lock` (stable since
//! Rust 1.89) — specifically that opening the same file a second time
//! from within the same process and calling `try_lock` yields
//! `TryLockError::WouldBlock` while the first handle lives.
//!
//! Two-process testing is out of scope (would need `std::process::Command`
//! with shared state); this test covers the in-process assumption which
//! is what our `acquire_single_instance_lock` depends on.
use std::fs::{OpenOptions, TryLockError};
use tempfile::TempDir;
#[test]
fn second_try_lock_on_same_file_blocks() {
let dir = TempDir::new().unwrap();
let path = dir.path().join("client.lock");
let first = OpenOptions::new()
.create(true)
.read(true)
.write(true)
.truncate(false)
.open(&path)
.unwrap();
first.try_lock().expect("first lock must succeed");
let second = OpenOptions::new()
.read(true)
.write(true)
.open(&path)
.unwrap();
match second.try_lock() {
Err(TryLockError::WouldBlock) => {}
Ok(()) => panic!("second try_lock unexpectedly succeeded"),
Err(e) => panic!("unexpected lock error: {e:?}"),
}
// Dropping `first` releases the OS lock; the third attempt then
// succeeds — proves the lock truly scopes to the file handle.
drop(first);
let third = OpenOptions::new()
.read(true)
.write(true)
.open(&path)
.unwrap();
third.try_lock().expect("after drop, re-lock must succeed");
}