fix(zset): mark a rebuild chunk's push as a step so a panicking push is counted (improvise-bw4p.5)
Also renames the MemTrace clone-panic test to what it asserts. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
committed by
Edward Langley
parent
b2445fed97
commit
8b0b715213
@@ -167,3 +167,27 @@ fn f4_a_failed_rebuild_step_in_a_txn_then_rollback_then_resume() {
|
||||
"[f4] header: a rebuild stepped in a rolled-back txn reports ZS_ERR_INTERRUPTED; got rc={rc} done={done}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f5_a_chunk_whose_push_overflows_in_a_txn_then_rollback_is_interrupted() {
|
||||
let (c, i, _s) = rig();
|
||||
let pending = zset(&[(b"a", i64::MAX)]);
|
||||
assert_eq!(unsafe { zs_circuit_push(c, i, pending) }, OK);
|
||||
let snap = zset(&[(b"a", 1), (b"b", 1)]);
|
||||
let mut job = null_mut();
|
||||
assert_eq!(unsafe { zs_rebuild_new(c, i, snap, 1, &mut job) }, OK);
|
||||
assert_eq!(unsafe { zs_circuit_begin(c) }, OK);
|
||||
let mut done = 0;
|
||||
assert_eq!(
|
||||
unsafe { zs_rebuild_step(job, c, None, null_mut(), &mut done) },
|
||||
Code::Overflow as i32,
|
||||
"the chunk's push overflows the pending delta"
|
||||
);
|
||||
assert_eq!(unsafe { zs_circuit_rollback(c) }, OK);
|
||||
let rc = unsafe { zs_rebuild_step(job, c, None, null_mut(), &mut done) };
|
||||
unsafe { zs_rebuild_free(job) };
|
||||
unsafe { zs_zset_free(snap) };
|
||||
unsafe { zs_zset_free(pending) };
|
||||
unsafe { zs_circuit_free(c) };
|
||||
assert_eq!(rc, Code::Interrupted as i32, "[f5] got rc={rc} done={done}");
|
||||
}
|
||||
|
||||
@@ -789,6 +789,7 @@ impl<K: Ord> Rebuild<K> {
|
||||
if chunk.is_zero() && self.began_at.is_some() {
|
||||
return Progress::Done;
|
||||
}
|
||||
circuit.stepped |= circuit.open.is_some();
|
||||
self.input.push(chunk);
|
||||
if self.began_at.is_some() {
|
||||
circuit.step_continue();
|
||||
|
||||
@@ -172,7 +172,7 @@ fn c1_a_clone_panic_anywhere_in_a_step_is_rolled_back() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn c2_memtrace_value_clone_panic_leaves_an_empty_group() {
|
||||
fn a_panicking_value_clone_leaves_a_memtrace_unchanged() {
|
||||
quiet();
|
||||
let mut t: MemTrace<u8, Boom> = MemTrace::new();
|
||||
CLONE_TRIP.with(|c| c.set(Some(0)));
|
||||
|
||||
@@ -142,3 +142,26 @@ fn b1_a_closure_that_reads_a_stream_during_eval_does_not_panic() {
|
||||
c.rollback();
|
||||
c.step();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn p1_a_chunk_whose_push_panics_in_a_txn_is_counted() {
|
||||
let mut c = Circuit::new();
|
||||
let (input, s) = c.input::<u8>();
|
||||
let i = c.integrate(&s);
|
||||
input.push(z(&[(1, i64::MAX)]));
|
||||
let mut job = Rebuild::new(input.clone(), z(&[(1, 1), (2, 1)]), 1);
|
||||
c.begin();
|
||||
let r = catch_unwind(AssertUnwindSafe(|| job.step(&mut c, || false)));
|
||||
assert!(r.is_err(), "the push overflows");
|
||||
c.rollback();
|
||||
let interrupted = job.interrupted(&c);
|
||||
let mut got = None;
|
||||
if !interrupted {
|
||||
while job.step(&mut c, || false) == Progress::Pending {}
|
||||
got = Some(i.current());
|
||||
}
|
||||
assert!(
|
||||
interrupted,
|
||||
"[p1] the chunk left the job unstepped; finishing it gives {got:?}"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user