test(process): complete ProcessManager edge contracts (#84) #100

Merged
gronod merged 1 commits from feat/84-process-manager-edge-contracts into milestone/m8-consolidation 2026-09-11 11:59:08 +01:00
Owner

Summary

Phase 4 of the M8 consolidation plan — completes the ProcessManager edge contracts.

Spawn log consolidation

  • Added a private logSpawn(id:binary:arguments:captured:) helper that consolidates the duplicated spawn logging in runStreaming and runCaptured. The exact spawn / spawn(captured) prefixes and LogSanitizer.sanitizeArgs behaviour are preserved.
  • No changes to EOF, stdin, cancellation, or continuation machinery; termination handlers still install before Process.run(); waitUntilExit watchdogs still start only after a successful launch; exactly-one finalisation guards remain in the actor. runStreaming and runCaptured stay distinct APIs.

New deterministic edge-case tests (ProcessManagerTests)

  • explicitPartialFlushEmitsRowColorsJSON — child prints an unterminated ROW_COLORS_JSON: payload, signals readiness via a marker file, then parks; the test calls flushPartialLine and asserts exactly one .jsonRow with the prefix stripped and no .stdout leak.
  • unterminatedRowTailFinalizesAsJSONRow — child prints an unterminated row prefix and exits; finalisation emits .jsonRow (not .stdout) before exactly one .exit.
  • fastStreamingExitEmitsExactlyOneExit — immediate child exit produces exactly one .exit after a grace window that outlasts the 2 s finalise watchdog.
  • fastCapturedExitEmitsExactlyOneExit — immediate captured exit returns status 7 and produces exactly one .exit event after both the termination-handler and waitUntilExit watchdog paths have fired.
  • capturedRunSetsArgyllNotInteractive — captured child sees ARGYLL_NOT_INTERACTIVE=1.
  • killAllTerminatesStreamingAndCapturedChildren — one streaming + one captured child registered concurrently; killAll() returns 2, both calls finish, both ids unregister, and each emits exactly one exit.

All tests use bounded timeouts and readiness marker files; every test cleans up its children.

Gate

xcodegen generate --spec project.yml && xcodebuild test -scheme ICCery -destination 'platform=macOS' -derivedDataPath build/DerivedData-feat-84-process-manager-edge-contracts ARCHS='arm64 x86_64' ONLY_ACTIVE_ARCH=NO CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY='-' -only-testing:ICCeryCoreTests/ProcessManagerTests -only-testing:ICCeryCoreTests/ProcessLineDecoderTests -only-testing:ICCeryCoreTests/JSONAccumulatorTests -only-testing:ICCeryCoreTests/LogSanitizerTests

TEST SUCCEEDED — 27 tests, 0 failures (ProcessManager 20, ProcessLineDecoder 3, JSONAccumulator 3, LogSanitizer 1).

Refs #84

## Summary Phase 4 of the M8 consolidation plan — completes the ProcessManager edge contracts. ### Spawn log consolidation - Added a private `logSpawn(id:binary:arguments:captured:)` helper that consolidates the duplicated spawn logging in `runStreaming` and `runCaptured`. The exact `spawn` / `spawn(captured)` prefixes and `LogSanitizer.sanitizeArgs` behaviour are preserved. - No changes to EOF, stdin, cancellation, or continuation machinery; termination handlers still install before `Process.run()`; `waitUntilExit` watchdogs still start only after a successful launch; exactly-one finalisation guards remain in the actor. `runStreaming` and `runCaptured` stay distinct APIs. ### New deterministic edge-case tests (`ProcessManagerTests`) - `explicitPartialFlushEmitsRowColorsJSON` — child prints an unterminated `ROW_COLORS_JSON:` payload, signals readiness via a marker file, then parks; the test calls `flushPartialLine` and asserts exactly one `.jsonRow` with the prefix stripped and no `.stdout` leak. - `unterminatedRowTailFinalizesAsJSONRow` — child prints an unterminated row prefix and exits; finalisation emits `.jsonRow` (not `.stdout`) before exactly one `.exit`. - `fastStreamingExitEmitsExactlyOneExit` — immediate child exit produces exactly one `.exit` after a grace window that outlasts the 2 s finalise watchdog. - `fastCapturedExitEmitsExactlyOneExit` — immediate captured exit returns status 7 and produces exactly one `.exit` event after both the termination-handler and `waitUntilExit` watchdog paths have fired. - `capturedRunSetsArgyllNotInteractive` — captured child sees `ARGYLL_NOT_INTERACTIVE=1`. - `killAllTerminatesStreamingAndCapturedChildren` — one streaming + one captured child registered concurrently; `killAll()` returns 2, both calls finish, both ids unregister, and each emits exactly one exit. All tests use bounded timeouts and readiness marker files; every test cleans up its children. ### Gate `xcodegen generate --spec project.yml && xcodebuild test -scheme ICCery -destination 'platform=macOS' -derivedDataPath build/DerivedData-feat-84-process-manager-edge-contracts ARCHS='arm64 x86_64' ONLY_ACTIVE_ARCH=NO CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY='-' -only-testing:ICCeryCoreTests/ProcessManagerTests -only-testing:ICCeryCoreTests/ProcessLineDecoderTests -only-testing:ICCeryCoreTests/JSONAccumulatorTests -only-testing:ICCeryCoreTests/LogSanitizerTests` **TEST SUCCEEDED** — 27 tests, 0 failures (ProcessManager 20, ProcessLineDecoder 3, JSONAccumulator 3, LogSanitizer 1). Refs #84
gronod added 1 commit 2026-09-11 11:37:13 +01:00
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
gronod self-assigned this 2026-09-11 11:37:24 +01:00
gronod added this to the M7 — Deduplicate & consolidate (develop) milestone 2026-09-11 11:37:24 +01:00
gronod merged commit 5e3b183b9a into milestone/m8-consolidation 2026-09-11 11:59:08 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/iccery-v2-mac#100