Skip to content

fix(tier-2): CodeRabbit follow-ups from PR #100#101

Merged
TinDang97 merged 1 commit into
mainfrom
fix/tier-2-cr-followup
May 24, 2026
Merged

fix(tier-2): CodeRabbit follow-ups from PR #100#101
TinDang97 merged 1 commit into
mainfrom
fix/tier-2-cr-followup

Conversation

@TinDang97
Copy link
Copy Markdown
Collaborator

@TinDang97 TinDang97 commented May 24, 2026

Summary

Closes the four remaining CodeRabbit findings from PR #100's review that the first fix wave didn't address.

Real bugs

  • src/cluster/command.rs::format_node_lineNodeFlags::Replica { master_id } was rendered as "slave <master_id>" inside the flags column AND the master-id was emitted again in its own dedicated column. The result was a malformed CLUSTER NODES / CLUSTER REPLICAS line where the master-id appeared twice and every column right of "flags" shifted by one. Flags is now "slave" / "myself,slave" only.
  • src/command/key_extra.rs COPY ... DB <idx> — the DB index token was consumed by `i += 1` without parsing. Any path that bypasses the handler-level intercept would silently accept garbage like `COPY src dst DB abc`. Now defensively `parse::()`s and returns the canonical `ERR value is not an integer or out of range` on malformed input.

Test hardening

  • `cluster_replicas_lists_replicas` was too loose (only checked >=9 fields). It would NOT have caught the duplicate-master-id bug above. Now pins exact 9-column layout, `fields[2] == "slave"`, master-id exactly once.

Script hygiene

  • `scripts/test-consistency.sh`: SWAPDB seed used `both SELECT 1; both DEL swapkey` — SELECT doesn't persist across separate `redis-cli` invocations, so DEL ran against db0 and erased the just-seeded key. Now uses explicit `-n ` per invocation.
  • OOR parity now requires both Redis and moon to return ERR (previous check ignored `$redis_oor`).

Scoped out (separate PR — design work, not a patch)

  • `src/shard/coordinator.rs` >1500 LOC → split (mechanical refactor, lands with parallel handler split).
  • Snapshot-COW interaction with `SwapDb` / `MOVE` in spsc_handler — needs design pass.

Verification

  • `cargo build --release` PASS
  • `cargo build --no-default-features --features runtime-tokio,jemalloc` PASS
  • `cargo clippy --release -- -D warnings` PASS
  • `cargo clippy --no-default-features --features runtime-tokio,jemalloc -- -D warnings` PASS
  • `cargo fmt --check` PASS
  • `cargo test --release --lib` — 3256 PASS / 0 FAIL
  • `cargo test --no-default-features --features runtime-tokio,jemalloc --lib` — 2649 PASS / 0 FAIL

Test plan

  • Unit tests (both runtimes)
  • Functional smoke: `COPY src dst DB abc` returns ERR; `COPY src dst DB 99999` returns ERR
  • Strengthened replica-line layout test would have caught the original bug
  • Reviewer: confirm flags-column change doesn't break any downstream consumer that depended on the malformed format

Summary by CodeRabbit

  • Bug Fixes

    • COPY command now validates the DB argument and rejects malformed syntax with appropriate error messages.
    • Fixed CLUSTER NODES/REPLICAS output formatting to correctly separate replica information columns.
  • Tests

    • Improved test determinism for database operations and error message validation.

Review Change Stack

Second pass on the CodeRabbit review surfaced four findings that the
previous fix wave did not address. This commit closes them all.

## Real bugs

- `src/cluster/command.rs::format_node_line`: `NodeFlags::Replica { master_id }`
  was rendered as `"slave <master_id>"` inside the flags column AND the
  master-id was emitted again in its own dedicated column. The result was a
  malformed `CLUSTER NODES` / `CLUSTER REPLICAS` line where the master-id
  appeared twice and every column right of "flags" shifted by one — breaking
  whitespace-tokenized parsers (including redis-cli's own splitter). Flags
  is now `"slave"` / `"myself,slave"` only; master-id stays in its own column.

- `src/command/key_extra.rs` `COPY ... DB <idx>`: the DB index token was
  consumed by `i += 1` without parsing. The handler-level intercept normally
  validates the DB index before reaching dispatch, but any path that
  bypassed the intercept (or future caller wiring) would silently accept
  garbage like `COPY src dst DB abc`. Now defensively `parse::<usize>()`s
  the token and returns the canonical `ERR value is not an integer or out
  of range` on malformed input.

## Test hardening

- `src/cluster/command.rs` test `cluster_replicas_lists_replicas`: was
  loose (only checked >=9 fields, gathered ids). It would not have caught
  the duplicate-master-id bug above. Now pins the exact replica-line
  layout: 9 whitespace-separated columns, `fields[2] == "slave"` (not
  "slave <master_id>"), `fields[3]` is exactly the 40-char master id, and
  the master-id appears exactly once on the line. Any future regression
  that re-embeds master-id in the flags column will flip the column count
  from 9 → 10 and trip the assertion.

## Script hygiene

- `scripts/test-consistency.sh` SWAPDB block:
  * Seed step previously used `both SELECT 0; both SET swapkey hello;
    both SELECT 1; both DEL swapkey`. `redis-cli SELECT` does NOT persist
    across separate invocations, so the trailing `DEL swapkey` ran against
    db0 and removed the key we had just seeded. Now uses explicit
    `redis-cli -n <db>` for each step.
  * Out-of-range parity check captured `$redis_oor` but only asserted
    `$rust_oor` contained `ERR`. A divergence (moon errors, Redis silently
    OKs) would have passed. Now requires both sides to return `ERR` and
    prints both messages on failure.

## Scoped out (intentionally not in this PR)

The remaining CodeRabbit comments need design work, not patches:

- `src/shard/coordinator.rs` is over the 1500-LOC cap. Splitting it out
  (e.g. `coordinator::swapdb`) is mechanical refactor work that belongs
  with the parallel `handler_{sharded,monoio}/mod.rs` split — they're all
  over the cap and should land together.
- Snapshot-COW interaction with `SwapDb` / `MOVE` in `src/shard/spsc_handler.rs`
  needs a design pass on snapshot reachability for two-DB commands, not a
  quick guard.

## Verification

- `cargo build --release` PASS
- `cargo build --no-default-features --features runtime-tokio,jemalloc` PASS
- `cargo clippy --release -- -D warnings` PASS
- `cargo clippy --no-default-features --features runtime-tokio,jemalloc -- -D warnings` PASS
- `cargo fmt --check` PASS
- `cargo test --release --lib` — 3256 PASS / 0 FAIL
- `cargo test --no-default-features --features runtime-tokio,jemalloc --lib` — 2649 PASS / 0 FAIL
- Functional: `COPY src dst DB abc` returns ERR; `COPY src dst DB 99999`
  returns ERR (out-of-range intercept still fires); CLUSTER REPLICAS
  layout verified by the strengthened unit test.

author: Tin Dang
@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@TinDang97 TinDang97 merged commit 4768250 into main May 24, 2026
2 of 7 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cce73c55-7f36-44ae-a295-e3e3e3511c52

📥 Commits

Reviewing files that changed from the base of the PR and between 22c4e40 and f8817a3.

📒 Files selected for processing (3)
  • scripts/test-consistency.sh
  • src/cluster/command.rs
  • src/command/key_extra.rs

📝 Walkthrough

Walkthrough

Three independent fixes improve command parsing, test determinism, and output formatting: COPY now rejects malformed DB arguments, SWAPDB tests use per-command database targeting for reproducibility, and CLUSTER NODES removes duplicate master-id embedding from replica flag fields.

Changes

Command handling and test improvements

Layer / File(s) Summary
COPY DB argument validation
src/command/key_extra.rs
COPY's DB branch now explicitly validates the following token as an integer, returning ERR syntax error if missing or ERR value is not an integer or out of range if invalid, preventing silent acceptance of malformed input.
SWAPDB test determinism and error parity
scripts/test-consistency.sh
SWAPDB setup now uses explicit per-command redis-cli -n <db> targeting instead of SELECT to seed and clear keys across databases. Out-of-range test now requires both Redis and moon outputs to contain ERR, printing both results on mismatch.
CLUSTER NODES replica flag formatting
src/cluster/command.rs
CLUSTER NODES flags_str now omits master-id from the flags token for replicas, using fixed keywords instead. Test enforces exactly 9 columns, validates flags equals slave, and ensures master-id appears exactly once per line.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • pilotspace/moon#99: The COPY DB argument parsing changes directly conflict with that PR's COPY DB handling being changed to a "not implemented" error and updated tests.

Poem

🐰 Three bugs brought to heel with focused care,
Copy validates, SWAPDB seeds fair,
CLUSTER formatting shines clean and bright—
Tests now lock in what's truly right! ✨

✨ 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 fix/tier-2-cr-followup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@TinDang97 TinDang97 deleted the fix/tier-2-cr-followup branch May 24, 2026 14:28
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