test: Provider-Level Log-Stop Failure Test Coverage - #173
Conversation
Add mutation-verified provider-level tests pinning the finalize-vs-finalizeQuietly stop contract from #168 (a failing write stream must report success: false, not be swallowed) — the prior registry-level tests never exercised a failing stream through a provider's stopLogCapture. Also documents two related behavior decisions (keep-unconditional-rejection, once-consumed-recorded-error) in logWriteStream.ts and docs/memory.
|
Warning Review limit reached
Next review available in: 7 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?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 reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. 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, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe change documents log-stream finalization error behavior and adds Android and iOS provider tests for asynchronous output-stream open failures. The tests verify ChangesProvider log-stop failure coverage
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/device-node/src/device/test/logCaptureProviders.test.ts (1)
241-251: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winShare the provider factory between platform loops.
The new loop duplicates the
createProviderfactory from Lines 121-130. Extract one helper that acceptsplatformandFakeChildProcess, then use it in both loops. This prevents Android and iOS test setup from diverging.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/device-node/src/device/test/logCaptureProviders.test.ts` around lines 241 - 251, Extract the duplicated createProvider factory into a shared helper that accepts a platform and FakeChildProcess and returns the corresponding AndroidLogcatProvider or IOSLogProvider. Replace the local factory definitions in both platform loops with this helper, preserving the existing execFileStub and spawnFn setup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/device-node/src/device/logWriteStream.ts`:
- Around line 191-202: Serialize concurrent stop operations in LogCaptureManager
before awaiting either provider, using a per-capture single-flight guard or
claiming the capture in _stoppedTestCases before the provider call so only one
stop can reach finalization. Preserve the required loud-before-quiet behavior
and update the comments in packages/device-node/src/device/logWriteStream.ts
(lines 191-202) and docs/memory/device-node/log-capture.md (lines 331-350) to
describe the enforced serialization and resulting ownership semantics.
- Around line 136-140: The finalize flow in logWriteStream.ts can report success
before asynchronous close-time errors are recorded. Update the writableFinished
path in finalize to await the stream’s terminal close/error state before
evaluating entry.error, add a regression test covering an error emitted during
auto-destroy after writableFinished, and update
docs/memory/device-node/log-capture.md lines 303-321 to document that successful
stop waits for close-time errors.
---
Nitpick comments:
In `@packages/device-node/src/device/test/logCaptureProviders.test.ts`:
- Around line 241-251: Extract the duplicated createProvider factory into a
shared helper that accepts a platform and FakeChildProcess and returns the
corresponding AndroidLogcatProvider or IOSLogProvider. Replace the local factory
definitions in both platform loops with this helper, preserving the existing
execFileStub and spawnFn setup.
🪄 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 Plus
Run ID: 01208b2a-49dc-4f21-8563-12e56bb5c55d
📒 Files selected for processing (7)
docs/memory/device-node/log-capture.mdfab/changes/260731-cjx8-provider-log-stop-test-coverage/.history.jsonlfab/changes/260731-cjx8-provider-log-stop-test-coverage/.status.yamlfab/changes/260731-cjx8-provider-log-stop-test-coverage/intake.mdfab/changes/260731-cjx8-provider-log-stop-test-coverage/plan.mdpackages/device-node/src/device/logWriteStream.tspackages/device-node/src/device/test/logCaptureProviders.test.ts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review should-fixes from the cjx8 pipeline: the finalize doc claimed the flush-succeeded-with-recorded-error state is unreachable with real errors, which holds only error-then-flush — auto-destroy's close(2) after finish can record an EIO with writableFinished already true, exactly what a writableFinished guard would drop. And finalizeQuietly's ordering note overstated _stoppedTestCases: it prevents only a sequential second stop; overlapping stop/abort is a check-then-act race (accepted hazard, recorded in docs/memory/device-node/log-capture.md). Comment-only; 122/122 device-node tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: Log Finalize Awaits Terminal Stream State LogWriteStreamRegistry.finalize decided success/failure by reading entry.error at whatever moment its finally completed, instead of after the stream's terminal close state. That produced two wrong outcomes: a fully-flushed log with a stale non-destroying recorded error rejected (contradicting the file's own contract), and a close-time error arriving after the check silently missed. finalize now awaits the stream's terminal 'close' state before deciding, and the success predicate is state-based: resolve iff writableFinished && stream.errored === null (warn-and-resolve over a stale recorded error), else reject with entry.error ?? stream.errored. Supersedes the PR #173 decision to document rather than fix the unconditional recorded-error rejection, reopened on two independent reviewers converging (operator-side should-fix; CodeRabbit MAJOR / data integrity). * Update ship status and record PR URL * fix: address review feedback from @coderabbitai[bot] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Update review-pr status Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: droid-ash <droid-ash@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Meta
cjx8generated by fab-kit v2.16.8
Pipeline: intake ✓ → apply ✓ → review ✓ → hydrate ✓ → ship → review-pr
Summary
PR #168 fixed a defect where
stopLogCapturereported success over a log file that was never written, but no test ever drove a failing write stream through a provider'sstopLogCapture— all prior tests either hitLogWriteStreamRegistrydirectly or used a good writable path. An adversarial mutation review proved this: swappingfinalizeforfinalizeQuietlyat the providers' success-path call sites restores the original defect and all 120 tests stay green. This change adds mutation-killing provider-level tests and documents two related behavior decisions without any source behavior change.Changes
success: false, an ENOENT-matching message, and zero live streams after stop — appended before the deliberately-last throwing-sink test, killing the finalize/finalizeQuietly mutationgit checkout, confirmed clean and green) — no committed artifactfinalize's unconditional recorded-error rejection (nowritableFinishedguard) — documented via rationale comment; the contradicting state is unreachable in production becauseautoDestroymeans every real error destroys the streamdocs/memory/device-node/log-capture.mdupdated with the new test surface and both Design DecisionsSummary by CodeRabbit
Bug Fixes
ENOENT, are propagated even after a successful flush.Tests
Documentation