Skip to content

refactor: extract shared wal frame codec#133

Merged
skel84 merged 3 commits intomainfrom
feat/extract-wal-frame
Mar 26, 2026
Merged

refactor: extract shared wal frame codec#133
skel84 merged 3 commits intomainfrom
feat/extract-wal-frame

Conversation

@skel84
Copy link
Copy Markdown
Owner

@skel84 skel84 commented Mar 26, 2026

Summary

  • extract the duplicated WAL frame codec into a shared allocdb-wal-frame crate
  • keep engine-local wal.rs wrappers so each engine preserves its own Frame surface and format constant
  • allow the trusted core to depend on this single internal frame-codec substrate crate

Testing

  • cargo test -p allocdb-wal-frame
  • cargo test -p allocdb-core wal -- --nocapture
  • cargo test -p quota-core wal -- --nocapture
  • cargo test -p reservation-core wal -- --nocapture
  • cargo clippy --all-targets --all-features -- -D warnings
  • scripts/check_repo.sh

Closes

Refs

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

Summary by CodeRabbit

  • Refactor
    • Extracted Write-Ahead Log (WAL) frame handling logic into a centralized shared module to eliminate code duplication and improve consistency across components. This consolidation enhances code maintainability without affecting end-user functionality.

Walkthrough

A new crate allocdb-wal-frame provides centralized WAL framing (encoding/decoding, checksum, scanning). Three crates (allocdb-core, quota-core, reservation-core) now depend on and re-export types from it; workspace and allowed-dependencies were updated to include the new crate.

Changes

Cohort / File(s) Summary
New WAL Frame Crate
crates/allocdb-wal-frame/Cargo.toml, crates/allocdb-wal-frame/src/lib.rs
Adds a new crate implementing WalFormat, RawFrame, encode_parts/decode_with/encoded_len_with, scan_frames_with, RecordType, DecodeError, ScanStopReason, checksum handling, and tests.
Workspace & Root
Cargo.toml, scripts/check_repo.sh
Workspace members updated to include crates/allocdb-wal-frame; scripts allowed-dependencies list updated to permit allocdb-wal-frame.
allocdb-core integration
crates/allocdb-core/Cargo.toml, crates/allocdb-core/src/wal.rs
Replaced local WAL framing logic with calls/re-exports to allocdb_wal_frame (RawFrame/WalFormat/scan_frames_with); dependency changed to local path.
quota-core integration
crates/quota-core/Cargo.toml, crates/quota-core/src/wal.rs
Replaced inline framing with allocdb_wal_frame APIs; added path dependency and adjusted crc32c version.
reservation-core integration
crates/reservation-core/Cargo.toml, crates/reservation-core/src/wal.rs
Replaced inline framing with allocdb_wal_frame APIs; added path dependency and adjusted crc32c version.

Sequence Diagram(s)

sequenceDiagram
  participant Engine as Engine Crate
  participant Wal as allocdb-wal-frame
  participant CRC as crc32c

  Engine->>Wal: encode_parts(format, lsn, slot, type, payload)
  Wal->>Wal: write header, fields, payload, zero checksum
  Wal->>CRC: compute CRC32C over bytes[format.checksum_start..]
  CRC-->>Wal: checksum
  Wal->>Wal: write checksum, return frame bytes

  Engine->>Wal: decode_with(bytes, format)
  Wal->>CRC: compute CRC32C (with checksum field zeroed)
  CRC-->>Wal: checksum
  Wal-->>Engine: RawFrame or DecodeError

  Engine->>Wal: scan_frames_with(bytes, format)
  Wal-->>Engine: ScanResult (frames, valid_up_to, stop_reason)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: extract shared wal frame codec' clearly and concisely summarizes the main change: extracting duplicated WAL frame codec logic into a shared crate.
Description check ✅ Passed The PR description covers the summary, testing approach, and issue references, though it omits the optional template sections for validation steps and docs updates.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/extract-wal-frame

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
crates/allocdb-wal-frame/src/lib.rs (1)

208-284: Consider expanding test coverage for negative paths.

Per coding guidelines, favor negative-path and invariant tests. The current suite covers round-trips and torn tails well, but could benefit from:

  • Invalid magic detection
  • Invalid version detection
  • Invalid record type detection
  • Corruption mid-scan (not just torn tail)
  • Empty payload edge case
  • BufferTooShort on header-only input
📝 Example additional tests
#[test]
fn invalid_magic_is_rejected() {
    let mut encoded = frame(1, 1, b"x").encode_with(FORMAT_FROM_HEADER);
    encoded[0] ^= 0xff; // corrupt magic
    assert!(matches!(
        RawFrame::decode_with(&encoded, FORMAT_FROM_HEADER),
        Err(DecodeError::InvalidMagic(_))
    ));
}

#[test]
fn invalid_version_is_rejected() {
    let mut encoded = frame(1, 1, b"x").encode_with(FORMAT_FROM_HEADER);
    encoded[4] = 0xff; // corrupt version
    encoded[5] = 0xff;
    assert!(matches!(
        RawFrame::decode_with(&encoded, FORMAT_FROM_HEADER),
        Err(DecodeError::InvalidVersion(_))
    ));
}

#[test]
fn header_only_returns_buffer_too_short() {
    let encoded = frame(1, 1, b"payload").encode_with(FORMAT_FROM_HEADER);
    assert_eq!(
        RawFrame::decode_with(&encoded[..HEADER_LEN], FORMAT_FROM_HEADER),
        Err(DecodeError::BufferTooShort)
    );
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/allocdb-wal-frame/src/lib.rs` around lines 208 - 284, Add
negative-path tests to the existing tests module to cover invalid magic, invalid
version, invalid record type, mid-scan corruption, empty payload, and
header-only BufferTooShort cases: create mutated encodings from the existing
frame(...) helper and assert RawFrame::decode_with returns the appropriate
DecodeError variants (InvalidMagic, InvalidVersion, InvalidRecordType,
BufferTooShort, etc.), and extend scan_frames_with cases to simulate mid-scan
corruption (corrupt bytes in the middle of the stream) and assert ScanStopReason
reflects the corruption; use HEADER_LEN, VERSION, FORMAT_FROM_HEADER /
FORMAT_AFTER_VERSION, RawFrame::decode_with, DecodeError and ScanStopReason
symbols to locate where to add these tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/allocdb-core/Cargo.toml`:
- Around line 9-10: Remove the unused direct dependency entry "crc32c" from
allocdb-core's Cargo.toml: delete the crc32c = "0.6.8" line (leaving
allocdb-wal-frame = { path = "../allocdb-wal-frame" } intact) since checksum
functionality is provided by allocdb-wal-frame; after removing, run a quick
cargo build to verify no unresolved references remain and update Cargo.lock if
needed.

In `@crates/allocdb-wal-frame/src/lib.rs`:
- Line 111: The conversion in decode_with currently uses
usize::try_from(payload_len).expect(...) which can panic on small-usize targets;
change it to mirror encoded_len_with by mapping the TryFromIntError into the
crate's error (PayloadTooLarge) and returning Err accordingly. Locate the
conversion in decode_with (the binding named payload_len) and replace the
expect-based conversion with a try_from(...).map_err(|_| Error::PayloadTooLarge
{ ... }) pattern consistent with encoded_len_with so decode_with returns a
PayloadTooLarge error instead of panicking.

---

Nitpick comments:
In `@crates/allocdb-wal-frame/src/lib.rs`:
- Around line 208-284: Add negative-path tests to the existing tests module to
cover invalid magic, invalid version, invalid record type, mid-scan corruption,
empty payload, and header-only BufferTooShort cases: create mutated encodings
from the existing frame(...) helper and assert RawFrame::decode_with returns the
appropriate DecodeError variants (InvalidMagic, InvalidVersion,
InvalidRecordType, BufferTooShort, etc.), and extend scan_frames_with cases to
simulate mid-scan corruption (corrupt bytes in the middle of the stream) and
assert ScanStopReason reflects the corruption; use HEADER_LEN, VERSION,
FORMAT_FROM_HEADER / FORMAT_AFTER_VERSION, RawFrame::decode_with, DecodeError
and ScanStopReason symbols to locate where to add these tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 00d779f1-dc6a-4a59-987b-65bd888b27d5

📥 Commits

Reviewing files that changed from the base of the PR and between d0cd674 and eaccb5b.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • Cargo.toml
  • crates/allocdb-core/Cargo.toml
  • crates/allocdb-core/src/wal.rs
  • crates/allocdb-wal-frame/Cargo.toml
  • crates/allocdb-wal-frame/src/lib.rs
  • crates/quota-core/Cargo.toml
  • crates/quota-core/src/wal.rs
  • crates/reservation-core/Cargo.toml
  • crates/reservation-core/src/wal.rs
  • scripts/check_repo.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: semgrep-cloud-platform/scan
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Write extensive tests for every meaningful behavior change. Favor invariant tests, negative-path tests, recovery tests, and regression tests over shallow happy-path coverage.
Add extensive logging where it materially improves debuggability or operational clarity. Use the right log level: error for invariant breaks, corruption, and failed operations that require intervention; warn for degraded but expected conditions such as overload, lag, or rejected requests; info for meaningful lifecycle and state-transition events; debug for detailed execution traces useful in development; trace only for very high-volume diagnostic detail.
Logging must be structured and purposeful. Do not add noisy logs that obscure signal or hide bugs.

Files:

  • crates/allocdb-core/src/wal.rs
  • crates/reservation-core/src/wal.rs
  • crates/allocdb-wal-frame/src/lib.rs
  • crates/quota-core/src/wal.rs
🔇 Additional comments (7)
Cargo.toml (1)

4-4: LGTM!

The new allocdb-wal-frame crate is correctly added to the workspace members.

scripts/check_repo.sh (1)

38-38: LGTM!

The allowed dependency list is correctly updated to include the new internal allocdb-wal-frame crate.

crates/allocdb-core/src/wal.rs (1)

1-95: LGTM!

Clean delegation to the shared allocdb_wal_frame crate while preserving the module's typed Frame surface with Lsn/Slot wrappers. The conversion helpers and scan function correctly map between raw and typed representations.

crates/quota-core/Cargo.toml (1)

9-10: No action needed—crc32c dependency is actively used.

The crc32c dependency is directly used in snapshot_file.rs (lines 67, 146 for checksum calculations) and should be retained.

			> Likely an incorrect or invalid review comment.
crates/reservation-core/Cargo.toml (1)

9-10: The crc32c dependency should be retained.

The crc32c crate is directly used in snapshot_file.rs for checksum computation and cannot be removed.

			> Likely an incorrect or invalid review comment.
crates/allocdb-wal-frame/Cargo.toml (1)

8-8: crc32c 0.6.8 is current and has no known security advisories.

crates/reservation-core/src/wal.rs (1)

6-9: Verify that reservation-core's original WAL format was not changed during extraction.

Both crates/reservation-core/src/wal.rs and crates/quota-core/src/wal.rs now have identical FORMAT constants (magic: 0x5154_424c, checksum_start: 6). If these crates previously had different magic values to enforce format isolation, this refactoring removes that fence. The current tests only round-trip frames produced by the same wrapper and cannot detect format drift.

Confirm whether reservation-core's original magic was 0x5154_424c or if it should be different. If it should differ, add a regression test that validates frames with the correct magic value (fixed wire format) cannot be decoded as the wrong format.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/allocdb-wal-frame/src/lib.rs`:
- Around line 250-301: Add negative-path tests covering invalid magic, invalid
version, invalid record type, ScanStopReason::Corruption, and the
encoded_len_with error paths: create tests that (1) tamper with the magic bytes
in an encoded frame and assert RawFrame::decode_with returns
Err(DecodeError::InvalidMagic) or equivalent, (2) modify the version bytes (the
two bytes at encoded[4..6]) and assert mismatch with VERSION causes decode
error, (3) corrupt the record type byte to an unknown value and assert decode
fails appropriately, (4) construct a byte stream that triggers scan_frames_with
to return ScanStopReason::Corruption (e.g., inconsistent header vs payload
length or bad checksum in middle) and assert scanned.stop_reason ==
ScanStopReason::Corruption, and (5) add tests that exercise
RawFrame::encoded_len_with error paths by calling encoded_len_with with
malformed inputs or formats to assert it returns the expected error; reference
functions/types RawFrame::decode_with, scan_frames_with, encoded_len_with,
ScanStopReason::Corruption, HEADER_LEN, VERSION, FORMAT_FROM_HEADER and
FORMAT_AFTER_VERSION to locate where to add these tests.
- Around line 126-129: The addition HEADER_LEN + payload_len should use
checked_add to prevent overflow on 32-bit usize: replace the unchecked let
frame_len = HEADER_LEN + payload_len with a checked_add that maps None to
Err(DecodeError::PayloadTooLarge) (same for the analogous addition near the
checksum/write path where frame length is computed); update both spots that
compute frame_len (the one after parsing payload_len and the later
checksum/write-size computation) to return DecodeError::PayloadTooLarge on
overflow, and add negative-path tests that pass u32::MAX and adjacent overflow
values to ensure the new checks prevent wrapping regressions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ad537c22-f2e6-477d-ae6d-90e583cb0e57

📥 Commits

Reviewing files that changed from the base of the PR and between eaccb5b and 7192eb0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • crates/allocdb-core/Cargo.toml
  • crates/allocdb-core/src/wal.rs
  • crates/allocdb-wal-frame/src/lib.rs
  • crates/quota-core/Cargo.toml
  • crates/quota-core/src/wal.rs
  • crates/reservation-core/Cargo.toml
  • crates/reservation-core/src/wal.rs
✅ Files skipped from review due to trivial changes (2)
  • crates/allocdb-core/Cargo.toml
  • crates/reservation-core/src/wal.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/reservation-core/Cargo.toml
  • crates/quota-core/Cargo.toml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: semgrep-cloud-platform/scan
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Write extensive tests for every meaningful behavior change. Favor invariant tests, negative-path tests, recovery tests, and regression tests over shallow happy-path coverage.
Add extensive logging where it materially improves debuggability or operational clarity. Use the right log level: error for invariant breaks, corruption, and failed operations that require intervention; warn for degraded but expected conditions such as overload, lag, or rejected requests; info for meaningful lifecycle and state-transition events; debug for detailed execution traces useful in development; trace only for very high-volume diagnostic detail.
Logging must be structured and purposeful. Do not add noisy logs that obscure signal or hide bugs.

Files:

  • crates/allocdb-core/src/wal.rs
  • crates/quota-core/src/wal.rs
  • crates/allocdb-wal-frame/src/lib.rs
🔇 Additional comments (2)
crates/allocdb-core/src/wal.rs (1)

37-43: Good extraction boundary.

Keeping Frame and ScanResult local while delegating the wire codec to allocdb-wal-frame removes the duplicated parser/CRC path without changing the engine-facing surface.

Also applies to: 57-90

crates/quota-core/src/wal.rs (1)

32-38: Nice thin-wrapper refactor.

This preserves the quota engine’s local Frame surface and format constant while reusing the shared codec for encode/decode/scan.

Also applies to: 42-65

@skel84
Copy link
Copy Markdown
Owner Author

skel84 commented Mar 26, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/allocdb-wal-frame/src/lib.rs`:
- Around line 7-10: WalFormat's public checksum_start can be out-of-range and
cause panics when encode/decode slice bytes[format.checksum_start..]; make the
invariant explicit by adding a constructor (e.g., WalFormat::new) that validates
checksum_start <= HEADER_LEN (or otherwise <= max supported offset) and/or make
the fields private so callers cannot set an invalid value, update code that
constructs WalFormat to use the new constructor, and add a regression test that
constructs a format at the maximum allowed checksum_start and verifies
encode/decode do not panic; apply the same validation/fix to the other WalFormat
constructions referenced near the other occurrences (around the spots noted at
98-99 and 137).
- Around line 246-277: Tests currently only round-trip frames created by frame()
(which always uses RecordType::ClientCommand) and thus miss byte-level/golden
compatibility and other record types; add invariant/golden tests that assert
exact encoded byte arrays for each WalFormat (FORMAT_FROM_HEADER and
FORMAT_AFTER_VERSION) using RawFrame::encode_with and RawFrame::decode_with, and
include explicit cases for RecordType::InternalCommand and
RecordType::SnapshotMarker (and a negative/regression case if decoding should
fail for malformed bytes); name tests to reflect format and record type (e.g.,
frame_golden_format_from_header_internal_command) so they pin the byte-level
layout rather than only round-tripping.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d18e70b8-421d-4c4d-adc0-93f9bdf81e9d

📥 Commits

Reviewing files that changed from the base of the PR and between 7192eb0 and 55ebbbf.

📒 Files selected for processing (1)
  • crates/allocdb-wal-frame/src/lib.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Write extensive tests for every meaningful behavior change. Favor invariant tests, negative-path tests, recovery tests, and regression tests over shallow happy-path coverage.
Add extensive logging where it materially improves debuggability or operational clarity. Use the right log level: error for invariant breaks, corruption, and failed operations that require intervention; warn for degraded but expected conditions such as overload, lag, or rejected requests; info for meaningful lifecycle and state-transition events; debug for detailed execution traces useful in development; trace only for very high-volume diagnostic detail.
Logging must be structured and purposeful. Do not add noisy logs that obscure signal or hide bugs.

Files:

  • crates/allocdb-wal-frame/src/lib.rs
🧠 Learnings (1)
📚 Learning: 2026-03-12T15:18:53.086Z
Learnt from: CR
Repo: skel84/allocdb PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-12T15:18:53.086Z
Learning: Applies to **/*.rs : Write extensive tests for every meaningful behavior change. Favor invariant tests, negative-path tests, recovery tests, and regression tests over shallow happy-path coverage.

Applied to files:

  • crates/allocdb-wal-frame/src/lib.rs
🔇 Additional comments (1)
crates/allocdb-wal-frame/src/lib.rs (1)

175-180: checked_frame_len is a good consolidation.

Centralizing the overflow guard here and covering the platform split in tests keeps decode_with and encoded_len_with aligned.

Also applies to: 395-403

Comment on lines +7 to +10
pub struct WalFormat {
pub magic: u32,
pub checksum_start: usize,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Validate checksum_start at the WalFormat boundary.

WalFormat is public, but both encode and decode slice bytes[format.checksum_start..] directly. Any value above HEADER_LEN panics on the supported empty-payload case, so a typo in an engine format constant turns into a process crash instead of a normal error path. Please enforce that invariant when constructing WalFormat (or make the fields private) and add a regression test around the maximum supported offset.

Also applies to: 98-99, 137-137

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/allocdb-wal-frame/src/lib.rs` around lines 7 - 10, WalFormat's public
checksum_start can be out-of-range and cause panics when encode/decode slice
bytes[format.checksum_start..]; make the invariant explicit by adding a
constructor (e.g., WalFormat::new) that validates checksum_start <= HEADER_LEN
(or otherwise <= max supported offset) and/or make the fields private so callers
cannot set an invalid value, update code that constructs WalFormat to use the
new constructor, and add a regression test that constructs a format at the
maximum allowed checksum_start and verifies encode/decode do not panic; apply
the same validation/fix to the other WalFormat constructions referenced near the
other occurrences (around the spots noted at 98-99 and 137).

Comment on lines +246 to +277
fn frame(lsn: u64, slot: u64, payload: &[u8]) -> RawFrame {
RawFrame {
lsn,
request_slot: slot,
record_type: RecordType::ClientCommand,
payload: payload.to_vec(),
}
}

#[test]
fn frame_round_trips_for_header_checksum_format() {
let encoded = frame(7, 11, b"abc").encode_with(FORMAT_FROM_HEADER);
let decoded = RawFrame::decode_with(&encoded, FORMAT_FROM_HEADER).unwrap();

assert_eq!(decoded, frame(7, 11, b"abc"));
}

#[test]
fn frame_round_trips_for_post_version_checksum_format() {
let encoded = frame(7, 11, b"abc").encode_with(FORMAT_AFTER_VERSION);
let decoded = RawFrame::decode_with(&encoded, FORMAT_AFTER_VERSION).unwrap();

assert_eq!(decoded, frame(7, 11, b"abc"));
}

#[test]
fn version_is_stable_and_shared() {
let encoded = frame(1, 2, b"x").encode_with(FORMAT_FROM_HEADER);
let version = u16::from_le_bytes(encoded[4..6].try_into().unwrap());

assert_eq!(version, VERSION);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Pin byte-level compatibility, not just round-trips.

frame() always uses RecordType::ClientCommand, and the positive-path tests only round-trip the extracted codec against itself. Since this PR is extracting the source of truth for existing WAL formats, please add fixed-byte/golden cases per WalFormat and cover InternalCommand/SnapshotMarker; otherwise a shared encode/decode drift can still pass here while breaking previously written WAL files.

As per coding guidelines, **/*.rs: Write extensive tests for every meaningful behavior change. Favor invariant tests, negative-path tests, recovery tests, and regression tests over shallow happy-path coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/allocdb-wal-frame/src/lib.rs` around lines 246 - 277, Tests currently
only round-trip frames created by frame() (which always uses
RecordType::ClientCommand) and thus miss byte-level/golden compatibility and
other record types; add invariant/golden tests that assert exact encoded byte
arrays for each WalFormat (FORMAT_FROM_HEADER and FORMAT_AFTER_VERSION) using
RawFrame::encode_with and RawFrame::decode_with, and include explicit cases for
RecordType::InternalCommand and RecordType::SnapshotMarker (and a
negative/regression case if decoding should fail for malformed bytes); name
tests to reflect format and record type (e.g.,
frame_golden_format_from_header_internal_command) so they pin the byte-level
layout rather than only round-tripping.

@skel84 skel84 merged commit 079f2fa into main Mar 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant