Skip to content
  • Mars.P's avatar
    ac09c544
    Add end-to-end ProcessAsync test for transient-pause (required + non-required) (#436) · ac09c544
    Mars.P authored
    * Add end-to-end ProcessAsync test for transient-pause (required + non-required)
    
    The P1b transient-pause fix (#434) was covered only compositionally: the
    unit tests mock the phase to throw the transient directly, and
    HalibutResumeReattachTests calls the strategy directly — neither runs the
    real ExecuteSingleActionAsync per-action catch THROUGH the runner to the
    pause outcome. The non-required path (no per-target catch) was the gap the
    adversarial review flagged.
    
    This drives the REAL pipeline: IDeploymentTaskExecutor.ProcessAsync over a
    seeded deployment (KubernetesAgent target, so the real
    HalibutMachineExecutionStrategy records the in-flight pointer), with only
    the Halibut RPC transport faked (GetStatus throws a transient
    HalibutClientException). It asserts, for BOTH required and non-required
    steps: task Paused (not Failed), checkpoint preserved, and the in-flight
    pointer preserved.
    
    Red-green verified: with the ExecuteSingleActionAsync transient catch
    neutered, the NON-required case fails (Paused → Failed + checkpoint
    deleted) — the exact swallow bug — while the required case still passes
    (the per-target catch covers it), confirming the test specifically guards
    the non-required propagation the fix added.
    
    * Tighten transient-pause E2E: typed pointer reader + permanent-failure contrast
    
    Replace the brittle Contains("\"t\"") substring with the production typed
    reader InFlightScriptMap.TryGet(json, DispatchSlot(...)) asserting the preserved
    pointer holds the EXACT ScriptTicket the strategy dispatched (captured in the
    fake) — pins slot identity + ticket value and survives a JsonPropertyName rename.
    
    Add a permanent-failure contrast case: the same seeded path with a permanent
    Halibut subtype (ServiceNotFoundHalibutClientException) must Fail terminally +
    delete the checkpoint, so the Paused rows read as "Paused iff transient" and the
    transient/permanent boundary is pinned end-to-end, not just in the predicate's
    own unit test.
    ac09c544
    Add end-to-end ProcessAsync test for transient-pause (required + non-required) (#436)
    Mars.P authored
    * Add end-to-end ProcessAsync test for transient-pause (required + non-required)
    
    The P1b transient-pause fix (#434) was covered only compositionally: the
    unit tests mock the phase to throw the transient directly, and
    HalibutResumeReattachTests calls the strategy directly — neither runs the
    real ExecuteSingleActionAsync per-action catch THROUGH the runner to the
    pause outcome. The non-required path (no per-target catch) was the gap the
    adversarial review flagged.
    
    This drives the REAL pipeline: IDeploymentTaskExecutor.ProcessAsync over a
    seeded deployment (KubernetesAgent target, so the real
    HalibutMachineExecutionStrategy records the in-flight pointer), with only
    the Halibut RPC transport faked (GetStatus throws a transient
    HalibutClientException). It asserts, for BOTH required and non-required
    steps: task Paused (not Failed), checkpoint preserved, and the in-flight
    pointer preserved.
    
    Red-green verified: with the ExecuteSingleActionAsync transient catch
    neutered, the NON-required case fails (Paused → Failed + checkpoint
    deleted) — the exact swallow bug — while the required case still passes
    (the per-target catch covers it), confirming the test specifically guards
    the non-required propagation the fix added.
    
    * Tighten transient-pause E2E: typed pointer reader + permanent-failure contrast
    
    Replace the brittle Contains("\"t\"") substring with the production typed
    reader InFlightScriptMap.TryGet(json, DispatchSlot(...)) asserting the preserved
    pointer holds the EXACT ScriptTicket the strategy dispatched (captured in the
    fake) — pins slot identity + ticket value and survives a JsonPropertyName rename.
    
    Add a permanent-failure contrast case: the same seeded path with a permanent
    Halibut subtype (ServiceNotFoundHalibutClientException) must Fail terminally +
    delete the checkpoint, so the Paused rows read as "Paused iff transient" and the
    transient/permanent boundary is pinned end-to-end, not just in the predicate's
    own unit test.
Loading