Repository navigation
ci(tests): fix AppDelegateShortcutRoutingTests teardown crash + make app-host backtraces cheap - #6412
Conversation
…ake app-host crash backtraces cheap Two layered fixes for the same CI symptom: the `tests` job was burning ~10 minutes per run on Swift crash backtraces, and crashes mid-suite can silently skip later test suites (the run is tolerated by parsing only the last summary). Root cause of the crashes: AppDelegateShortcutRoutingTests.setUpWithError() throws XCTSkip on headless CI runners (no window server honors makeKeyAndOrderFront) BEFORE it assigns the implicitly-unwrapped `originalSettingsFileStore`. XCTest still runs tearDown() after a skip, and tearDown force-unwrapped that nil -> "Fatal error: Unexpectedly found nil" -> app-host crash. Every skipped test in the class (~23 per run) crashed this way. Fix 1 (the crash): make `originalSettingsFileStore` a regular optional and guard the restore in tearDown, so tearDown tolerates setUp bailing out early. This is runner-agnostic; it also runs on real machines unchanged. Root cause of the 80s+ stalls: each crash ran a fully symbolicated, interactive Swift backtrace because the crash happens in the XCTest host process (cmux DEV.app), which never received the job-level SWIFT_BACKTRACE env. Only xcodebuild itself got it. Fix 2 (never-again, durable): xcodebuild_noninteractive.py now exports TEST_RUNNER_SWIFT_BACKTRACE before launching xcodebuild. xcodebuild copies TEST_RUNNER_-prefixed vars (prefix stripped) into the test host's environment, so ANY future app-host crash gets interactive=no,symbolicate=off and returns in well under a second instead of 80s+. This covers every app-host test invocation that already routes through the wrapper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthrough
ChangesTest teardown safety and CI backtrace default
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~4 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 21 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (21 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The teardown nil-guard and its comment add 4 lines to the already-large AppDelegateShortcutRoutingTests.swift; refresh its entry in .github/swift-file-length-budget.tsv to accept that known debt.
The
testsjob has been burning ~10 minutes per run on Swift crash backtraces, and the crashes can silently skip later test suites. Both come from one class.Why (root cause)
AppDelegateShortcutRoutingTests.setUpWithError()throwsXCTSkipon headless CI runners (no window server honorsmakeKeyAndOrderFront) before it assigns the implicitly-unwrappedoriginalSettingsFileStore. XCTest still runstearDown()after a skip, and tearDown force-unwrapped that nil →Fatal error: Unexpectedly found nil→ app-host crash. On a headless runner every test in the class skips, so this fired ~23 times per run (confirmed in thetestslog).Each crash then ran a fully symbolicated, interactive Swift backtrace taking 80–87s, because the crash happens in the XCTest host process (
cmux DEV.app), which never received the job-levelSWIFT_BACKTRACE— onlyxcodebuilditself did. ~23 × ~83s explains most of the gap between thetestsjob (~25 min) and the rest of CI (seconds to ~2 min on Blacksmith).This is not a Blacksmith vs Warp issue (the
testsjob runs on Warp); it reproduces on any headless macOS runner.Fixes
originalSettingsFileStorebecomes a regular optional andtearDownguards the restore (if let …), so tearDown toleratessetUpbailing early. Runner-agnostic; behavior on real machines is unchanged.scripts/ci/xcodebuild_noninteractive.pynow exportsTEST_RUNNER_SWIFT_BACKTRACEbefore launching xcodebuild. xcodebuild copiesTEST_RUNNER_-prefixed vars (prefix stripped) into the test host environment, so any future app-host crash getsinteractive=no,symbolicate=offand returns in well under a second instead of 80s+. One place, covers every app-host test invocation already routed through the wrapper.Verification
testslog before this PR: ~23Unexpectedly found nilcrashes from this class + multipleBacktrace took 8Xs. After: those crashes are gone (the skipped tests tear down cleanly), and the wrapper keeps any unrelated future crash from stalling CI. CI on this PR is the proof.Out of scope (noted, not fixed here)
Index out of range while reading buffercrash inpreservesNonSecretString— separate bug, separate PR.🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
Low Risk
Test teardown and CI wrapper env only; no production app behavior changes.
Overview
Stops headless CI from repeatedly crashing the XCTest app host when
AppDelegateShortcutRoutingTestsskips insetUpWithError()before saving the keyboard shortcut file store.originalSettingsFileStoreis no longer an implicitly unwrapped optional;tearDown()only restoresKeyboardShortcutSettings.settingsFileStorewhen setup actually assigned it, so skipped tests tear down cleanly instead of force-unwrapping nil.The CI
xcodebuild_noninteractive.pywrapper now setsTEST_RUNNER_SWIFT_BACKTRACE(from jobSWIFT_BACKTRACEor a fast default) so the test host gets non-interactive, non-symbolicated backtraces—cutting ~80s hangs per app-host crash across all wrapped test runs.Reviewed by Cursor Bugbot for commit 16eec1b. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Fixes a teardown crash in
AppDelegateShortcutRoutingTestson headless CI and makes app-host Swift crash backtraces non-interactive and fast, removing long stalls and preventing skipped suites.originalSettingsFileStoreoptional and guarded its restore intearDown(), so tests thatXCTSkipinsetUpWithError()don’t crash the app host.scripts/ci/xcodebuild_noninteractive.py, exportTEST_RUNNER_SWIFT_BACKTRACE(fromSWIFT_BACKTRACEor a fast default) so the test host getsinteractive=no,symbolicate=off; app-host crashes now return quickly instead of hanging..github/swift-file-length-budget.tsvto allow the extra lines added by the teardown nil-guard.Written for commit 16eec1b. Summary will update on new commits.
Summary by CodeRabbit
Tests
Chores