• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bedrock-kv / bedrock / 12776d422a8e4313b36a1a15d80b06815c91a3f9
82%

Build:
DEFAULT BRANCH: develop
Ran 26 Aug 2026 04:26PM UTC
Jobs 1
Files 217
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

26 Aug 2026 04:08PM UTC coverage: 78.59% (+0.04%) from 78.548%
12776d422a8e4313b36a1a15d80b06815c91a3f9

push

github

web-flow
Make the foreman's health verdict independent of worker order (#214)

Closes bedrock-287.

`compute_health_from_worker_info/1` was a pairwise fold whose clause
`{:ok, _}, _ -> :starting` overwrote an already-recorded failure, so the
verdict depended on the order workers arrived in:

| input | old | new |
|---|---|---|
| `[ok, bad, bad]` | `{:failed_to_start, _}` | `{:failed_to_start, _}` |
| `[bad, bad, ok]` | `:starting` | `{:failed_to_start, _}` |
| `[ok, bad]` | `:starting` | `{:failed_to_start, _}` |
| `[bad]` | `:starting` | `{:failed_to_start, _}` |

`recompute_health/1` folds `Map.values(t.workers)`, and small Erlang
maps iterate in term order — so whether a wedged worker was reported
came down to how worker ids sort. Exhaustively: over every multiset of
size 1–3 drawn from the four reachable health shapes, **18 distinct
multisets change verdict under permutation**. The last row is the
starkest — a foreman hosting exactly one worker, and that worker failed
to start, reported `:starting`.

A second bug shared the clause list: `:stopped` matched only the
catch-all, so a still-starting worker yielded `:unknown`.

### Approach
State the verdict as precedence over the whole collection rather than as
a pairwise fold, so order-independence is structural instead of
something to re-derive clause by clause.

### No caller can observe a difference in what anything actually reads
The `:ok` / not-`:ok` partition is **identical** before and after: the
old fold could only reach `:ok` via `{:ok, _}, :ok` and never re-entered
it once it left, so both versions return `:ok` exactly when every worker
is running. Both consumers (`do_wait_for_healthy/2`,
`notify_waiting_for_healthy/1`) match `:ok` literally.

`:unknown` is kept and is **not** dead code — `Foreman.report_health/3`
accepts `Worker.health()`, which includes `{:error, :timeout |
:unavailable}`, and that reaches this field.

### Verification
2803 tests, 0 failures. Credo and dialyzer clean.

Adversariall... (continued)

9 of 10 new or added lines in 1 file covered. (90.0%)

6802 of 8655 relevant lines covered (78.59%)

1046.31 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
90.0
47.14% lib/bedrock/service/foreman/health.ex
Jobs
ID Job ID Ran Files Coverage
1 12776d422a8e4313b36a1a15d80b06815c91a3f9.1 26 Aug 2026 04:26PM UTC 217
78.59
GitHub Action Run
Source Files on build 12776d422a8e4313b36a1a15d80b06815c91a3f9
  • Tree
  • List 217
  • Changed 2
  • Source Changed 0
  • Coverage Changed 2
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • 12776d42 on github
  • Prev Build on develop (#734FAABA...)
  • Next Build on develop (#21616497...)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc