Skip to content

feat: accept the full compose-go duration grammar for healthcheck interval#68

Merged
lesnik512 merged 5 commits into
mainfrom
healthcheck-duration-grammar
Jul 16, 2026
Merged

feat: accept the full compose-go duration grammar for healthcheck interval#68
lesnik512 merged 5 commits into
mainfrom
healthcheck-duration-grammar

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Rewrites healthcheck.interval_seconds to parse the full compose-go duration grammar the way docker compose config v5.1.2 does — closing the compound/hour healthcheck-duration over-reject — and closes two hard-rule false greens found along the way.

Design and rationale: planning/changes/2026-07-16.03-healthcheck-duration-grammar.md.

What changed

  • interval_seconds now parses the complete compose-go duration grammar → whole seconds: all units incl. d (days) and w (weeks), compound (1h30m), fractional (1.5d), and sign (-1h). interval paces compose2pod's own wait_healthy loop and never reaches podman, so it can honor the full set. timeout/start_period (emitted verbatim to podman's Go-parser --health-*, no d/w) are unchanged — a legitimate refusal under rule two.
  • False green Port the compose-to-podman-pod converter into compose2pod #1 (whitespace): dropped the old .strip(). Padded durations (interval: " 5s ") were accepted while Docker rejects all whitespace — a hard-rule violation the flat matrix never probed (interval is nested). Guarded by a both-reject conformance corpus doc using a genuine demonstrator (a value the old strip-parser accepted).
  • False green Adopt planning-convention v1.1.2 and migrate planning docs #2 (trailing newline): the anchored regex used $, which in Python matches before a trailing \n, so interval: | block scalars ("5s\n") slipped through. Switched to \Z; guarded by a block-scalar corpus doc.
  • Overflow-safe (math.isfinite before int()), so a giant duration raises cleanly.

Verification

  • 1368 tests @ 100% line coverage; just lint-ci, just check-planning clean.
  • Conformance: healthcheck_compound_duration/healthcheck_hour_duration flip over-reject → conformant (with dedicated both-accept assertions); the two new false-green guards are both-reject. Over-rejection count 6 → 4.

Follow-up (separate change)

The trailing-\n $-vs-\Z flaw is systemic across the other regex-anchored values.py grammars (_SIZE, _DURATION, _PORT, _STRICT_INT_STRINGmem_limit, ports, timeout, etc.), all pre-existing. Scoped out of this PR by design; a dedicated change will close the class.

🤖 Generated with Claude Code

…green

" 1h " never demonstrated the old .strip()-based interval_seconds defect --
the old parser had no h unit, so it rejected " 1h " regardless of stripping.
" 5s " is the genuine demonstrator: the old parser stripped it to "5s" and
silently accepted it, while Docker refuses any whitespace in a duration.
_INTERVAL_DURATION's trailing $ matched before a trailing newline in
Python's non-MULTILINE mode, so a YAML block scalar like
`interval: |\n  5s\n` was wrongly accepted as 5s even though
`docker compose config` rejects "5s\n" outright. Switch to \Z, which
anchors only at the true end of the string.
@lesnik512
lesnik512 merged commit 184a6c5 into main Jul 16, 2026
13 of 16 checks passed
@lesnik512
lesnik512 deleted the healthcheck-duration-grammar branch July 16, 2026 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant