Files
Marcos Paulo 6b863d2d2d feat(vault): wave 1 implementation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 18:59:06 -03:00

60 lines
2.1 KiB
Rust

//! The vault lock file (SPEC §4.2).
mod common;
use std::fs;
use notescraft_vault::{Error, Vault};
/// A pid no live process can have on Linux or macOS.
const DEAD_PID: u32 = 4_294_967_294;
#[test]
fn opening_creates_the_private_state_folder_and_the_lock() {
let (dir, vault) = common::vault("lock");
let lock = dir.path().join(".notescraft/lock");
assert!(vault.root().is_dir());
assert!(lock.is_file());
let content = fs::read_to_string(&lock).unwrap();
assert_eq!(content.split_whitespace().next().unwrap(), std::process::id().to_string());
assert_eq!(vault.root(), fs::canonicalize(dir.path()).unwrap());
}
#[test]
fn a_second_instance_is_locked_out() {
let (dir, _vault) = common::vault("locked");
let err = Vault::open(dir.path()).expect_err("second writer");
assert!(matches!(err, Error::Locked { pid } if pid == std::process::id()), "{err:?}");
}
#[test]
fn a_lock_owned_by_a_dead_process_is_taken_over() {
let dir = common::TempDir::new("takeover");
fs::create_dir_all(dir.path().join(".notescraft")).unwrap();
fs::write(dir.path().join(".notescraft/lock"), format!("{DEAD_PID} 1700000000")).unwrap();
let vault = Vault::open(dir.path()).expect("stale lock must be taken over");
let content = fs::read_to_string(dir.path().join(".notescraft/lock")).unwrap();
assert_eq!(content.split_whitespace().next().unwrap(), std::process::id().to_string());
drop(vault);
}
#[test]
fn dropping_the_vault_releases_the_lock() {
let dir = common::TempDir::new("release");
drop(Vault::open(dir.path()).unwrap());
assert!(!dir.path().join(".notescraft/lock").exists());
// The lock is free again, and a second take-over works.
drop(Vault::open(dir.path()).expect("lock released"));
}
#[test]
fn read_only_open_does_not_take_the_lock() {
let dir = common::TempDir::new("ro-lock");
let read_only = Vault::open_read_only(dir.path()).unwrap();
assert!(!dir.path().join(".notescraft/lock").exists());
let writer = Vault::open(dir.path()).expect("read-only opens leave the lock free");
assert!(writer.root().is_dir());
drop(read_only);
}