Skip to content

fix: mxcli test --watch never recovers a failed rebuild on a long-lived serve process - #1787

Draft
MendixMau wants to merge 2 commits into
mendixlabs:mainfrom
MendixMau:feature/1786-watch-recovery
Draft

MendixMau wants to merge 2 commits into
mendixlabs:mainfrom
MendixMau:feature/1786-watch-recovery

Conversation

@MendixMau

Copy link
Copy Markdown
Contributor

Closes #1786

Why

mxcli test --local --watch keeps one mxbuild --serve process alive for
the whole watch session and rebuilds through it on every change — a test
file edit or a model change. run --local --watch has had build-failure
recovery (restart the serve process, rebuild once more) for a while;
test --watch never had it wired in. On macOS (mxbuild 11.15.0), the
second build in a serve process fails on regenerated page/layout files,
and mxbuild reports that failure by resource key
(IO_PathNotFound_Path) rather than the English text the existing
recovery matches — so every model change after the first in a test --watch session reports ERROR the change could not be applied and the
loop never produces a verdict again.

What changed

  • localapp.go: route test --watch rebuilds through serveRecovery
    (the same mechanism run --local --watch already uses), in headless
    mode.
  • webclient_legacy_paths.go: recognize the resource-key form of the
    failure (IO_PathNotFound_Path) alongside the existing English-text
    match, including when the target directory exists but the specific file
    mxbuild wants does not.
  • serve_recovery.go: a headless flag — nothing serves the client in a
    test run, so an incomplete web/dist after an otherwise-successful
    build is not a defect worth another restart+rebuild (that restart exists
    only for run --local --watch's browser-facing client).

How tested

Unit tests for the two previously-untested edges this change exercises:

  • TestServeRecovery_HeadlessSkipsPrebuiltRestart
  • TestLegacyClientBuildHintRecognizesMacOSKeyForm
  • TestLegacyClientBuildHintMacOSKeyForm_DirExistsFileMissing
go test ./cmd/mxcli/docker/... -run 'TestServeRecovery_HeadlessSkipsPrebuiltRestart|TestLegacyClientBuildHintRecognizesMacOSKeyForm|TestLegacyClientBuildHintMacOSKeyForm_DirExistsFileMissing'
→ PASS (3/3)

Full cmd/mxcli/docker package suite: 2 failures, both pre-existing and
unrelated to this change — TestSyncJavaDependencies_ReturnsWhenOrphanedDaemonHoldsPipe
and TestSyncJavaDependencies_FailingMxStillFails, exercising the
orphan-pipe/Gradle-daemon watchdog in javadeps.go (a file this PR never
touches; diff is localapp.go, serve_recovery.go(+test),
webclient_legacy_paths.go(+test) only). Confirmed environment-only:
setsid is absent on this machine (the fake-mx test script needs it),
and the same test fails identically against vanilla origin/main at
f99080e93 with zero code from this PR applied (15.01s, same message).

Real-app repro and numbers

Against a copy of a real ~280MB Mendix app (~/mta-lab/w/w2test, a copy of
sl1, 13 tests across 2 .test.mdl files):

mxcli test tests/mdl/69-match-rules.test.mdl tests/mdl/120-slice1-behaviour-changes.test.mdl \
  --local --watch --db-type hsqldb --require-assertions -p App.mpr
step time result load (1-min avg)
boot 86s 13/13 green —
test-file edit, wrong @expect 23s 12/13 (1 red) —
revert 22s 13/13 green —
model bug (seeded ACT_Invoice_Pay pay-guard removal) 61s 12/13, test_5 red — a correct verdict 46-58
model revert 64s 13/13 green —
broken model (CE1613, retrieve from a deleted entity) 21s Errors: 1, Passed: 0 — never a pass —

These are correctness numbers, not a speed claim: the machine was under
heavy concurrent load (other sessions) for this run. The property being
proven is that the model-bug step gets a verdict at all — before this
fix, that exact step errors with "could not be applied" every time on
macOS and the watch loop is stuck for the rest of the session.

Regression evidence

  • Wrong @expect → red. Revert → green. (test-file-only loop, unaffected
    by this change, included as a control.)
  • Seeded model bug → correct red verdict, not an error.
  • Model revert → correct green verdict.
  • Broken microflow (CE1613) → reported as an error, never a pass.
  • Watch session shuts down cleanly on SIGINT and restores the project.

Known limitation

This recovers from the build failing in the prebuilt-client shape. If
mxbuild --serve itself dies (not just a failed build), test --watch
still needs a full session restart — out of scope here, which only wires
the existing run --local --watch recovery machinery into the path
test --watch never had it on.

Checklist

  • Full-stack MDL: n/a (no new syntax)
  • Test coverage: 3 new unit tests for previously-untested edges, plus
    real-app ABAB and 5 applicable negative controls
  • Version compat: no change to generated MDL or project file format
  • Security: no change to the test-endpoint's attack surface
  • Scope: one concern per PR (watch-mode build recovery only)
  • Documentation: behavior change is internal recovery, no user-facing
    flag or doc change needed

Marked as draft until CI confirms green (the 2 pre-existing, unrelated
docker package failures are documented above with cross-branch proof).

🤖 Generated with Claude Code

…m IO_PathNotFound, headless test runs)

Rebuild in the test runner's app called serve.Build directly, so the recovery that run --local --watch has never ran for test --watch: the second build of a serve process fails on regenerated pages (mxbuild 11.15 macOS reports IO_PathNotFound_Path, not the English text) and every later change reported 'could not be applied'. Route through serveRecovery, match the key form, and skip the web/dist completeness restart (headless) .

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 191261bcfa68e22f6915084f0553880d08cecbff)

(refs mendixlabs#1786)
…OS/Linux key-form failure

Two gaps in existing coverage for the test --watch build-recovery fix:
- serveRecovery.headless must skip the prebuilt-bundle restart entirely
  (only a browser-facing client cares about a lost dist/pages).
- missingClientDirs must recognize mxbuild's resource-key form of the
  same failure (IO_PathNotFound_Path, measured on 11.15.0 macOS) as well
  as the English-text form, including when the directory exists but the
  specific file mxbuild wants does not.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

fix: mxcli test --watch never recovers a failed rebuild on a long-lived serve process (macOS IO_PathNotFound_Path)

1 participant