mirror of
https://github.com/telemt/telemt.git
synced 2026-11-03 22:31:59 +03:00
WEB Manager Session + Generation Fence tests
This commit is contained in:
@@ -11,6 +11,8 @@ use nix::fcntl::{Flock, FlockArg, OFlag, openat, renameat};
|
||||
use nix::sys::stat::Mode;
|
||||
#[cfg(unix)]
|
||||
use nix::unistd::{UnlinkatFlags, fsync, unlinkat};
|
||||
#[cfg(unix)]
|
||||
use tracing::warn;
|
||||
|
||||
use super::compute_source_revision;
|
||||
use crate::api::model::ApiFailure;
|
||||
@@ -75,7 +77,7 @@ impl ConfigWriteLock {
|
||||
}
|
||||
}
|
||||
|
||||
/// Replaces one config source through a durable same-directory rename.
|
||||
/// Replaces one config source through a same-directory rename after syncing file data.
|
||||
pub(in crate::api) async fn write_atomic(
|
||||
path: PathBuf,
|
||||
contents: String,
|
||||
@@ -362,7 +364,15 @@ fn write_and_publish(
|
||||
anchored.name(),
|
||||
)
|
||||
.map_err(errno_to_io)?;
|
||||
fsync(anchored.parent()).map_err(errno_to_io)?;
|
||||
// Rename is the commit boundary. A later directory-sync error cannot be reported as an
|
||||
// uncommitted mutation because mandatory in-process publication must still run.
|
||||
if let Err(error) = fsync(anchored.parent()).map_err(errno_to_io) {
|
||||
warn!(
|
||||
path = %path.display(),
|
||||
%error,
|
||||
"Config rename committed but directory durability sync failed"
|
||||
);
|
||||
}
|
||||
Ok(committed_revision)
|
||||
}
|
||||
|
||||
|
||||
@@ -346,13 +346,13 @@ async fn config_sidecar_lock_serializes_competing_revision_writers() {
|
||||
let second = second.await.unwrap();
|
||||
|
||||
assert_ne!(first.is_ok(), second.is_ok());
|
||||
let conflict = if let Err(error) = first {
|
||||
error
|
||||
} else {
|
||||
second.unwrap_err()
|
||||
let (winner_revision, conflict) = match (first, second) {
|
||||
(Ok(revision), Err(error)) | (Err(error), Ok(revision)) => (revision, error),
|
||||
_ => unreachable!("exactly one cooperative writer must commit"),
|
||||
};
|
||||
assert_eq!(conflict.code, "revision_conflict");
|
||||
let persisted = tokio::fs::read_to_string(path).await.unwrap();
|
||||
assert_eq!(winner_revision, current_revision(&path).await.unwrap());
|
||||
let persisted = tokio::fs::read_to_string(&path).await.unwrap();
|
||||
assert!(persisted.contains("first.example") || persisted.contains("second.example"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user