You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The split catch-up tests counted frames but never read their bytes, so
a chunk walk shipping the right NUMBER of frames while overlapping or
skipping ids passed them all. That is the silent-NULL corruption
vector: the server null-pads a gapped delta, and a row referencing a
padded id lands a NULL symbol with no error anywhere. Mutating the
walk's start-id advance proves the gap -- the alignment suite stayed
17/17 green while only the 25-second end-to-end test noticed.
CatchUpCapturingClient now keeps each frame's bytes, joining the two
slices of a multipart send, and assertCatchUpReassembles folds them
through QwpWireTestUtils.accumulateDeltaDictionary -- the decoder the
end-to-end handler already uses -- then compares per id. Comparing
content rather than ranges catches overlap, gap and shift alike, and
each frame is checked against the advertised cap. QwpWireTestUtils and
that one method turn public for the sf.cursor package; the rest of the
class stays package-private.
Add three tests: a three-way split whose chunks must tile [0, n)
exactly; an empty-dictionary reconnect that must ship no catch-up
frame, using cap 0 so the guard rather than an empty walk holds the
count at zero; and a variable-width split, the only test that catches
a walk assuming a uniform entry stride.
Cover multi-byte UTF-8 on the persist path, which nothing exercised:
every symbol in these suites was ASCII, where a symbol's UTF-8 byte
length and its char count agree. Replacing Utf8s.utf8Bytes with
String.length leaves DeltaDictRecoveryTest 23/23 green while the new
round-trip test fails on the truncated tail. The literals carry a
runtime self-check so the test cannot decay into an ASCII one should
the file ever lose its encoding.
Drop a comment block left stranded above WebSocketResponse when its
field was removed, and rewrite two that described an entry-end index
this class never had. Correct the surviving Invariant B text: the
reconnect budget reaches connectWithRetry from ensureConnected's SYNC
branch and BackgroundDrainer's capability-gap deadline, never
buildAndConnect and never this loop.
Tear the torn-dict guard test down recursively. It builds the slot
layout under <dir>/default, which the flat helper cannot remove, so
every run left the whole tree behind.
Production behaviour is unchanged: every main/ hunk is comment text.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: core/src/test/java/io/questdb/client/test/cutlass/qwp/client/sf/cursor/CursorWebSocketSendLoopCatchUpAlignmentTest.java
Copy file name to clipboardExpand all lines: core/src/test/java/io/questdb/client/test/cutlass/qwp/client/sf/cursor/CursorWebSocketSendLoopTornDictGuardTest.java
+5-1Lines changed: 5 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -72,7 +72,11 @@ public void setUp() {
72
72
73
73
@After
74
74
publicvoidtearDown() {
75
-
TestUtils.removeTmpDir(sfDir);
75
+
// Recursive: this test builds the store-and-forward slot layout
76
+
// (<dir>/default/... plus <dir>/.slot-locks/...), and the flat variant
77
+
// cannot remove a non-empty subdirectory -- it also discards its result,
78
+
// so the whole tree survived every run unnoticed.
0 commit comments