0c66fc6010
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.
50 lines
1.6 KiB
Rust
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");
|
|
}
|