Skip to content

test_exec_bash hook test fails on macOS due to PTY output not captured by mocked logger #560

Description

@raballew

Description

The test_exec_bash test in jumpstarter-common fails consistently on macOS CI runners (macos-15, Python 3.11) while passing on Linux. The root cause is that PTY output written by hook subprocesses is not fully drained before the test assertions run, causing the mocked logger to miss expected log lines.

Root Cause

In python/packages/jumpstarter/jumpstarter/exporter/hooks.py, the HookExecutor._run_hook method uses a PTY for subprocess output capture. On macOS, the PTY I/O timing differs from Linux -- the async reader task may not have consumed all output by the time it is cancelled after the subprocess exits. There is no drain step to read remaining buffered data from the PTY file descriptor after the reader task stops.

Affected CI

  • Workflow: Python CI (python.yml)
  • Runner: macos-15
  • Python version: 3.11
  • Test: test_exec_bash in python/packages/jumpstarter/jumpstarter/exporter/hooks_test.py
  • Failure pattern: Persistent (fails on every macOS run)

Reproduction

Run the test suite for jumpstarter-common on macOS:

cd python && make pkg-test-jumpstarter_common

The test passes on Linux but fails on macOS because the mocked logger does not receive the expected output lines.

Expected Behavior

test_exec_bash should pass on both Linux and macOS, with all hook subprocess output captured by the logger regardless of platform PTY timing differences.

Proposed Fix

  1. After the async reader task is cancelled, drain any remaining data from the PTY file descriptor synchronously before closing it
  2. Bound the drain loop to prevent indefinite blocking (max iterations + timeout)
  3. Properly handle OSError during drain (PTY may already be closed)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions