tests: review 003 Findings 2-3 — pre-release dispositions
Finding 2(a) landed: a one-shot cfg(test) generation-top LISTEN-pause seam on the pg forwarder (listen_pause in seam.rs) lets the LISTEN-window death test kill the fresh reconnect generation's backend before its snapshot LISTEN — the LISTEN then fails honestly (57P01 terminating) and the production fall-through arm (listen_ok == false) runs unmodified. The harness test pins the honest mid-reconnect transient, full recovery (wake, re-issue recovery of the refused mid-gap registration), and the exactly-one-wake differentiator; a server-less unit pin covers the flag. Finding 2(b) + the defensive arms stay parked with the code-read as pin, recorded in the task file with current line refs. Finding 3 landed: the rollback_fault seam (commit-fault mechanics) feeds SQLITE_FULL-shaped errors into both ROLLBACK failure drop paths — SqliteTxHandle::drop and the cancelled op's ConnLease::drop — exercised in one test (phases: open-handle drop; single-poll-then-drop mid-op cancellation), pinning slot replenish via reopen, no ghosts, and the store staying usable.
This commit is contained in:
1 parent
c132714a77
commit
c3a0c54df0
8 files changed
+670
-10
No files matched your search
@@ -59,6 +59,14 @@ pub struct SqliteStore {
|
||||
/// arm. Dead in production builds.
|
||||
#[cfg(test)]
|
||||
commit_fault: crate::seam::commit_fault::Flag,
|
||||
/// The store's rollback-fault arm (review 003 Finding 3) — born
|
||||
/// disarmed; a test arms it through
|
||||
/// [`SqliteStore::arm_rollback_fault`] so the next ROLLBACK on a
|
||||
/// drop path (the handle's or the cancelled op's lease's) fails
|
||||
/// through the real rollback-failure drop arms. Dead in production
|
||||
/// builds.
|
||||
#[cfg(test)]
|
||||
rollback_fault: crate::seam::rollback_fault::Flag,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for SqliteStore {
|
||||
@@ -90,6 +98,18 @@ impl SqliteStore {
|
||||
pub(crate) fn arm_commit_fault(&self) {
|
||||
crate::seam::commit_fault::arm(&self.commit_fault)
|
||||
}
|
||||
|
||||
/// Arm the rollback-fault seam (review 003 Finding 3): the next
|
||||
/// `ROLLBACK` on a drop path of this store (a transaction handle
|
||||
/// dropped open, or a tx-op future dropped mid-op) fails with a
|
||||
/// `SQLITE_FULL`-shaped driver error and replenishes the writer
|
||||
/// slot through the real rollback-failure drop arm. One-store
|
||||
/// scoping (disarms on first consumption) keeps parallel test
|
||||
/// stores unaffected.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn arm_rollback_fault(&self) {
|
||||
crate::seam::rollback_fault::arm(&self.rollback_fault)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SqliteStore {
|
||||
@@ -130,6 +150,8 @@ pub(crate) fn open_store(path: &str, opts: SqliteOpts) -> alkstore::Result<Sqlit
|
||||
closed: Arc::new(AtomicBool::new(false)),
|
||||
#[cfg(test)]
|
||||
commit_fault: crate::seam::commit_fault::disarmed(),
|
||||
#[cfg(test)]
|
||||
rollback_fault: crate::seam::rollback_fault::disarmed(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -143,7 +165,12 @@ impl Store for SqliteStore {
|
||||
dyn Fn() -> alkstore::Result<rusqlite::Connection> + Send + Sync,
|
||||
> = std::sync::Arc::new(move || crate::seam::open_writer_connection(&db_path));
|
||||
#[cfg(test)]
|
||||
let fut = crate::tx::SqliteTxHandle::begin(writer, reopen, self.commit_fault.clone());
|
||||
let fut = crate::tx::SqliteTxHandle::begin(
|
||||
writer,
|
||||
reopen,
|
||||
self.commit_fault.clone(),
|
||||
self.rollback_fault.clone(),
|
||||
);
|
||||
#[cfg(not(test))]
|
||||
let fut = crate::tx::SqliteTxHandle::begin(writer, reopen);
|
||||
fut
|
||||
|
||||
Reference in new issue
Block a user