Skip to content

wheels test cannot run a 500+ spec suite — HTTP client dies with 'Read timed out' before returning any result #3352

Description

@bpamiri

Wheels 4.0.5 / Lucee 7.0.0.395. A project whose own wheels test cannot run its own suite is a CI fragility rather than a local annoyance, so filing it separately from any single spec.

Symptom

On a suite of ~500 specs taking roughly 2.5 minutes, wheels test fails with

Read timed out

and produces no result at all — not a failure report, a crashed runner. There is no partial output to work from and no indication whether the specs passed.

The same suite runs fine when the app-test JSON endpoint is hit directly with a generous client-side timeout:

curl -s -m 900 "http://<host>/wheels/testbox?format=json&useTestDB=true"

which returns the full report. So the specs and the runner are fine — the CLI's HTTP client is giving up.

Why it matters

  • The failure is indistinguishable from a hung app to anyone who has not seen it before. Ours cost real time before someone tried curl.
  • It scales in: the suite worked, then silently stopped working as it grew past roughly 140s / 400 specs. There is no warning, and the threshold depends on machine speed, so it can pass locally and fail in CI.
  • It pushes projects off the supported path. Our CI now bypasses wheels test entirely and curls the endpoint with an explicit timeout, which means we no longer get whatever the CLI adds.

Ask

A configurable client-side read timeout on wheels test (flag and/or setting), defaulting high enough that a multi-minute suite completes. Streaming or heartbeat output would additionally make a long run legible rather than looking hung.

Adjacent, possibly the same fix

?directory=tests.specs.<name> scopes a run to one subdirectory and returns in seconds — very useful, and it is what makes iteration bearable under this bug. Two notes from using it heavily:

  • It does not appear to be documented anywhere we could find. Worth surfacing; it is the main workaround.
  • bundles= is accepted but silently ignored — no error, and the full suite runs. Silently ignoring a filter argument is worse than rejecting it, because the run looks scoped. Happy to file that separately if you would rather keep the issues split.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions