Skip to content

Add unit tests for arg-parser, cron intervals, and job notifier - #592

Merged
selfcontained merged 1 commit into
mainfrom
agt_2b661328e2c1/job-test-enforcer-5adb2541
May 22, 2026
Merged

Add unit tests for arg-parser, cron intervals, and job notifier#592
selfcontained merged 1 commit into
mainfrom
agt_2b661328e2c1/job-test-enforcer-5adb2541

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

Summary

Test-enforcer coverage additions — 45 new unit tests targeting previously untested or under-tested pure logic.

  • templates/arg-parser.ts (28 tests, new file): Comprehensive coverage for the template argument parser — regex matching, modifier parsing (required, multiline, textarea), case-insensitive deduplication, modifier merging across duplicate placeholders, substitution with required-arg validation, and edge cases (empty specs, whitespace-only names, no-content delimiters).

  • jobs/cron.tsvalidateCronInterval (5 tests): Previously untested function that enforces the 5-minute minimum cron interval. Covers accept/reject boundary, under-threshold intervals (1m, 2m), invalid expressions, and single-fire schedules.

  • jobs/job-notifier.ts (12 tests): Duration formatting in Slack payloads (ms, seconds, minutes, hours, boundary values), mrkdwn escaping for special characters (&, <, >), timed_out status label, crashed status routing, pendingQuestion fallback for needs_input, and defensive handling of undefined notify config.

Test plan

  • pnpm run check passes
  • pnpm run test — server 1266 tests passed, web 64 tests passed
  • pnpm run test:e2e — 144 passed, 12 skipped (terminal-live/tmux)

🤖 Generated with Claude Code

…ier edge cases
Coverage additions from test-enforcer run: 28 new tests for the previously untested
template arg-parser (parsing, modifier merging, deduplication, substitution), 5 tests
for the untested cron interval validator, and 12 tests for job notifier gaps (duration
formatting, mrkdwn escaping, status routing, defensive config handling).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@selfcontained
selfcontained merged commit 6be2847 into mainMay 22, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_2b661328e2c1/job-test-enforcer-5adb2541 branch May 22, 2026 02:28
selfcontained added a commit that referenced this pull request Aug 7, 2026
python3 was first invoked after the fixture had already pinned the
symlink, rewritten the unit, and removed the fixed runtime — a VM
without Python would be stranded half-converted with migrations still
marked applied. Preflight python3/systemctl/sed/ln/cp and the user
systemd manager before touching anything, and make the
applied-migrations rewrite atomic (tmp + os.replace).
infra-review #592 item #1262.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
selfcontained added a commit that referenced this pull request Aug 8, 2026
…896)
* Harden assisted update against legacy pinned-symlink Linux installs
On ≤v0.31.x Linux installs whose ExecStart resolves through a symlink
hard-pinned to a versioned dist/bun binary, the managed-update-first
ordering in migration 0010 extracted the target release but restarted
back into the old runtime, whose boot-time release-binary pruning then
deleted the new artifact — while validations false-greened because they
trusted release.json rather than the running executable.
- Reorder migration 0010 for Linux legacy shapes: inspect the entrypoint
first and perform the fixed-runtime cutover (stage exact checksum-
verified target, preserve .previous, activate fixed path, repoint
ExecStart) BEFORE the first restart; macOS keeps the launchd bridge.
Adds legacy bin/dispatch symlink + unit-backup hygiene and makes
rollback prefer the fixed runtime .previous over legacy unit backups.
- New running_version required check that proves the actually running
executable via the X-Dispatch-Version header; the assisted framework
enforces it implicitly at launch and at check-run time (manifests
can't name it yet — pre-v0.33 parsers reject unknown check names).
- expected_runtime_artifact now uses lstat and rejects a symlinked
fixed runtime path.
- Manifest requiredChecks schema accepts unknown well-formed names so
future check additions can't silently drop a whole migration on older
installs; unknown names fail closed at run time instead. A test
guards that shipped manifests stay within the legacy-parser-safe set.
- VM fixture script (scripts/vm-fixtures/legacy-pinned-symlink.sh) that
converts a healthy Linux install into the pinned-symlink legacy shape
for the documented VM validation row.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Ensure KillMode=process lands before 0010's Linux cutover restart
On a legacy host both fixed-runtime-entrypoint (0010) and
agent-restart-safety (0011) are pending and run in numeric order, so
0010's new cutover restart happened before 0011 added KillMode=process —
terminating the tmux-backed assisted agent inside dispatch.service's
control group at exactly that first restart. 0010 now adds
KillMode=process + daemon-reload as a required pre-restart step (the
only permitted unit change besides the ExecStart repoint), intentionally
front-running 0011.
0011's alreadySatisfied is now config-based (systemctl show -p KillMode,
no behavioral restart probe), non-systemd hosts are an explicit no-op
terminal state, and its instructions acknowledge 0010 may have already
applied the setting.
Review feedback from the Ubuntu VM validation agent on PR #896.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Preflight fixture dependencies before destructive conversion
python3 was first invoked after the fixture had already pinned the
symlink, rewritten the unit, and removed the fixed runtime — a VM
without Python would be stranded half-converted with migrations still
marked applied. Preflight python3/systemctl/sed/ln/cp and the user
systemd manager before touching anything, and make the
applied-migrations rewrite atomic (tmp + os.replace).
infra-review #592 item #1262.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Make 0010's platform/shape branches explicit
Architecture review flagged two literal-reading hazards: the Linux
staging/activation steps were phrased unconditionally, so an
already-fixed Linux entrypoint could be steered into a manual cutover
that bypasses the managed update; and the platform-generic .previous
preservation step, read after the Linux cutover, would overwrite the
run's only rollback artifact with the target binary.
Instructions are now explicit branches: Branch A (Linux already-fixed:
managed update only), Branch B (Linux legacy pinned: staged cutover
before first restart, with "never overwrite the .previous this step
created"), Branch C (macOS bridge, including the deleted-inode .previous
recovery and plist work), plus shared restart-safety, hygiene, and
verification steps keyed to their branches.
architecture-review #593 items #1263 #1264.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto 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

@selfcontained