test: mutation-harden LibOpConditions coverage#536
Conversation
Adversarial mutation testing of LibOpConditions surfaced three surviving mutants, all in the odd-input (reason-carrying) code paths: - end calc that ignores oddInputs (reason slot included in the loop range) - output placement for odd inputs (sub(end, 0x20) instead of end) - removal of the no-condition-met revert guard The existing reference-check fuzz test truncates odd inputs to even, so the odd-input success path was never asserted, and the no-condition-met revert was masked by the reference implementation's own revert. Add discriminating tests: - eval of conditions with an odd number of inputs where a condition is met, asserting the matched value (3-input and 5-input cases) - a direct run() call asserting the output stack-top placement for an odd-input match (pointer, not just value) - direct run() revert tests (isolated from the reference implementation) for the no-condition-met case, both even (empty reason) and odd (trailing reason) Tests-only; no source changes. All three mutants are now killed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 45 minutes and 40 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (37)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Summary
Scoped adversarial mutation-testing pass on
LibOpConditions(src/lib/op/logic/LibOpConditions.sol). Tests-only; no source changes.git diff src/is empty.LibOpConditionsreturns the value of the first nonzero condition in a pairwise condition/value list; if the input count is odd the trailing input is an error-reason string used when no condition is met. Itsrunhas subtle odd/even handling (loop range, output placement, reason read, and a no-match revert).Mutation matrix
Mutated each behavior in
LibOpConditions.sol, ranLibOpConditionsTest, recorded SURVIVED/KILLED, restored after each.> 2boundaryoddInputs := mod(inputs, 2)→mod(inputs, 3)endcalc dropsoddInputs(includes reason slot in loop)sub(end, iszero(odd)*0x20)→sub(end, 0x20)→ endmload(end)→mload(cursor)+0x40→+0x20!isZero→isZeroif (conditionIsZero)→if (false))8/11 killed by the existing suite. The three survivors all hid in the odd-input (reason-carrying) paths:
testOpConditionsRun) truncates odd inputs to even, so the odd-input success path was never asserted — R2 and R3 hid there.opReferenceCheck, whose reference implementation also reverts, masking a missing revert inrunitself — R9 hid there.New tests (all pass clean on baseline; each fails under its target mutant)
testOpConditionsEval3InputsTrueOddReason/testOpConditionsEval5InputsSecondTrueOddReason— eval ofconditionswith an odd input count where a condition is met; assert the matched value, trailing reason ignored. (kills R2)testOpConditionsRunOddMatchStackTopPlacement— directrun()call asserting the output stack-top pointer (words consumed), not just the value, for an odd-input match. (kills R3)testOpConditionsRunRevertsNoMatchEven/testOpConditionsRunRevertsNoMatchOddReason— callrun()in isolation (newrunExternalwrapper, no reference fn) and assert it reverts with the correct reason (empty for even, trailing reason for odd). (kills R9)Remaining-gaps checklist
Verification
forge build: Compiler run successful (theboolean-cstlint warnings are pre-existing, unrelated to this diff).forge fmt --checkon the test file: clean.LibOpConditionsTest: 20 passed, 0 failed.test/src/lib/op/logic/*): 181 passed, 0 failed..gas-snapshotchange (no new opcode / bytecode change), so no regen needed.Conflict-avoidance with #535
Touches only
test/src/lib/op/logic/LibOpConditions.t.sol. No overlap with #535's files (LibAllStandardOps.sol,LibOpPi.sol,src/generated/*.pointers.sol, parse-meta,LibOpE/LibOpPi). No.gas-snapshotedit.🤖 Generated with Claude Code