Skip to content

test: Ollama CI stalls fail the quality matrix in three shapes; #1369 retry covers only one #1589

Description

@planetf1

Problem

The quality matrix still intermittently fails on the live-Ollama telemetry
tests even after #1318 (mocked tracing coverage) and #1369 (auto-retry on
ReadTimeout). Ollama intermittently stalls requests on the loaded
ubuntu-latest CPU runners, and that stall surfaces as three different
failure shapes
— only one of which the current retry net covers.

Observed behaviour

Evidence from completed public runs (all code-checks / quality jobs):

Run Branch / model Failed test Failure shape Covered by #1369 retry?
32758965363 (2026-08-24, main merge queue, Granite 4.1) pr-1564 test_ollama_generate_from_raw_metrics_integration Ollama returned an empty response (response='', done=True, warning from generate_from_raw), no tokens recorded, assert (None is not None) No — AssertionError matches no pattern
32950575498 (2026-08-26, PR #1587, Granite 4.2) 0c7c9023 predecessor test_litellm_token_metrics_integration[non-streaming] + 2 native tracing/metrics tests 900 s pytest-timeout watchdog kill (litellm path) + httpx.ReadTimeout ×2 (retries exhausted) Partially — native ReadTimeout retried, litellm watchdog not
32972890653 (2026-08-26, PR #1587, Granite 4.2) 0c7c9023 test_litellm_token_metrics_integration[non-streaming] + 3 native tracing tests Same: watchdog kill + 9 consecutive ~300 s httpx.ReadTimeouts (3 tests × 3 attempts) Partially, as above

Notes:

  • The failing tests differ between runs on the same SHA set (different
    tracing tests fail each time), consistent with a nondeterministic
    server-side stall rather than a test defect. In run 32972890653 the same
    model served requests in 2–77 s immediately before and after a ~45-minute
    stall window, with slow-but-passing calls at 173 s and 242 s bracketing
    the native backend's 300 s timeout.
  • The litellm watchdog shape is mechanical, not just bad luck:
    LiteLLMBackend passes no request deadline to litellm.acompletion, so
    litellm falls back to a 600 s per-attempt timeout, the OpenAI SDK
    silently retries a stalled attempt (verified: 3 attempts against a stalled
    socket), and only_rerun="ReadTimeout" never matched the litellm path's
    litellm.exceptions.Timeout (message embeds APITimeoutError). A single
    stall therefore consumed the whole per-attempt budget with no retry.
  • Server-side cause of the stalls is unknown: the quality workflow ran
    nohup ollama serve & without capturing output, so job logs contained
    zero server lines across the ~90-minute test window.

Expected behaviour

  • A stalled live-Ollama request should surface as a bounded, retryable
    timeout on every backend path, and the run should be diagnosable from the
    job log without re-implementing the server-side investigation.

Reproduce

Run the quality workflow repeatedly on a Granite live-test branch (CPU
runners, Ollama 0.32.2). Stalls occur intermittently; runs 32950575498 /
32972890653 above are fixed records of the failure shapes.

Already addressed by PR #1587

  • The litellm live test is bounded to the same 300 s the native
    OllamaModelBackend uses, with num_retries: 0, so one pytest attempt
    can no longer exceed the 900 s watchdog budget.
  • The flaky marker now retries both timeout shapes
    (OLLAMA_TIMEOUT_RERUN_PATTERNS, regression-pinned in
    test/test_flaky_ollama_rerun.py).
  • The workflow captures the Ollama server log and dumps it on failure, so
    the first subsequent red run carries server-side evidence.

Remaining work (tracked here)

  1. Diagnose the server-side stall cause from the first red run with server
    logs (memory/page-cache pressure on shared runners, Ollama scheduler
    behaviour, model loading under concurrency).
  2. Decide handling for the empty-response shape (seen on main, run
    32758965363): generate_from_raw currently logs a warning and returns an
    empty string, which downstream tests turn into assert None is not None
    — a failure shape no retry pattern can match. Options: retry on the
    empty-response warning, or make the backend surface a typed error.
  3. Reassess whether the retry budget (2 reruns) is adequate once the stall
    cause is known, or whether live telemetry tests need a dedicated
    warmup/keep-alive strategy.

Related: #1318 (closed), #1367 (closed), #1369 (merged), #1296, PR #1587.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions