Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ParallelTestRunner"
uuid = "d3525ed8-44d0-4b2c-a655-542cee43accc"
authors = ["Valentin Churavy <v.churavy@gmail.com>"]
version = "2.7.0"
version = "2.8.0"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
49 changes: 49 additions & 0 deletions docs/src/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,53 @@ duration, longest first) and their results appear in the same overall summary.
If the user filters tests via positional arguments (e.g. `julia test/runtests.jl unit`),
any serial test names that were filtered out are silently removed from the serial list.

## Failure Handling

Both options described in this section are opt-in and default to off.

### Recycling Workers after a Failure

Workers are reused across tests, so a test that corrupts process-wide state — a wedged GPU driver whose every subsequent allocation fails, a global left in an inconsistent state, a library put in an unusable configuration — can make every later test scheduled on that same worker fail too.

Setting `recycle_on_failure=true` stops the worker after any test that did not pass, so the next test gets a fresh process:

```julia
runtests(MyPackage, ARGS; recycle_on_failure=true)
```

This complements the existing recycling of workers exceeding `max_worker_rss` and of workers that crashed outright.

### Retrying Failed Tests

When several workers compete for a limited resource (usually memory), a failure can mean "lost the race for the resource" rather than "the code is broken".
Such a test typically passes when run on its own.

The `retries` keyword argument re-runs tests that did not pass, up to `N` times, after the main run has completed:

```julia
runtests(MyPackage, ARGS; retries=1)
```

Retried tests run **sequentially on a single fresh worker**, so a test that failed only because of concurrent resource pressure gets an otherwise-idle system.
If a test fails again, its worker is stopped before the next retry, so one failure cannot contaminate the following one.

Only the final attempt of each test is recorded in the results, so a test that passes on retry is reported as passing and a persistently broken test is reported as failing.
Retries are visible in the output, so flakiness is surfaced rather than hidden:

```
Retrying 1 failed test (1)
fails (8) │ 0.05 │ failed at 2026-08-08T15:10:15.526
```

!!! note
Retries are skipped when the run was interrupted (e.g. `Ctrl+C`) or when `--quickfail` is
in effect, since in both cases the run stopped early on purpose.

!!! tip
`recycle_on_failure` and `retries` address different halves of the same problem and work
well together: recycling keeps one bad test from cascading onto its worker during the run,
while retries give the tests that did fail a contention-free second chance.

## Custom Workers

For tests that require specific environment variables or Julia flags, you can use the `test_worker` keyword argument to [`runtests`](@ref) to assign tests to custom workers:
Expand Down Expand Up @@ -303,3 +350,5 @@ function jltest {
1. **Use custom workers sparingly**: Custom workers add overhead. Only use them when tests genuinely require different configurations.

1. **Use `serial` for resource-intensive tests**: If a test allocates significant memory or uses exclusive hardware resources, mark it as serial rather than reducing `--jobs` globally. This keeps the rest of your suite running in parallel.

1. **Only use `retries` for worker contention-related failures**: Not all intermittent failures are caused by parallel worker resource contention. Ensure you aren't masking real test failures when using this feature.
10 changes: 10 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ The `serial` keyword argument to [`runtests`](@ref) lets you designate specific
for sequential execution, either before or after the parallel batch.
See [Serial Tests](@ref) in the advanced usage guide for details.

### Failure Recycling and Retries

Workers are recycled when they crash or exceed the memory threshold.
Additionally, [`runtests`](@ref) has two keyword arguments to further customize
failure hanlding. Setting `recycle_on_failure=true` recycles a worker after any
failed test, so a test that corrupts process-wide state cannot poison later tests,
and `retries=N` re-runs failed tests sequentially up to `N` times to reduce false
failures caused by resource contention.
See [Failure Handling](@ref) in the advanced usage guide for details.

### Real-time Progress

The test runner provides real-time output showing:
Expand Down
Loading