Repository navigation
perf(tests): stop the slowest app-host unit tests waiting out real timeouts #13752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
teamleaderleo
wants to merge
74
commits into
manaflow-ai:main
from
teamleaderleo:perf/app-host-slow-tests
Closed
Changes from all commits
Commits
Show all changes
74 commits
Select commit
Hold shift + click to select a range
196d7b9
test(terminal): restore the presented-surface fixture contract so pac…
austinywang 258b283
fix(popover): stop rewriting the presentation binding during view update
austinywang b30b030
test(cloud): satisfy the plus menu's sign-in gate and route Cmd+Y thr…
austinywang 13fad29
test(chrome): assert the composited Bonsplit chrome contract instead …
austinywang 626112b
test(tmux): wait for the main window to adopt the mirror pane before …
austinywang b3755b8
test(browser): report the refused connection through the navigation d…
austinywang dbdcd23
fix(cloud): scope reserved-workspace cleanup to its pending card and …
austinywang 0d6df3a
fix(cli): restore deferred socket connection, explicit SSH control op…
austinywang b602efb
test(cli): align CLI integration fixtures with the shipped hook, SSH,…
austinywang 18e3c96
test(workspace): restore the app-host repairs for fork, focus recover…
austinywang 70ecc1a
fix(restore): keep a restore identity when the persisted surface id c…
austinywang 9f258dd
test(terminal): align snapshot, projection, terminal, and browser fix…
austinywang 77bfa38
test(browser): align lifecycle, identity, host-view, loopback bridge,…
austinywang 1e62556
test(terminal): wait for asynchronous runtime creation in the remaini…
austinywang cbc73f7
test(cli): model surface.respawn for respawn-pane and give the Codex …
austinywang 366492b
fix(socket): keep mobile.panel.artifact.fetch off the local socket an…
austinywang 5510126
test(remote): align tmux seed transport, SSH, socket command, and por…
austinywang a956dae
repair: refresh full-suite fixes on current main
teamleaderleo 2c55871
test: align mobile artifact fetch lane assertion
teamleaderleo d5cedc9
Merge remote-tracking branch 'origin/main' into fix/main-ci-full-suite
austinywang e6926fb
repair: close remaining full-suite contracts
austinywang 4c22264
Merge remote-tracking branch 'origin/main' into fix/main-ci-full-suite
austinywang 84e70db
test(restore,sidebar): align two stale contracts with shipped behavior
austinywang c875d8d
Merge remote-tracking branch 'upstream/main' into fix/app-host-green
teamleaderleo 3dc91b2
test: give Cloud catalog tests live destination workspaces
teamleaderleo 4d1f51e
chore: normalize pbxproj after live workspace fixture
teamleaderleo 999b359
fix: admit agent renames of agent-owned accepted Cloud names
teamleaderleo 17381ac
test: expect adopted machine rows to keep the pending create identity
teamleaderleo 70eaf44
fix: restore per-display noVNC targets and refresh stale Cloud tests
teamleaderleo 42ae036
fix: publish every guest display from daemon graph updates
teamleaderleo e167c15
test: fence the fake Cloud projection reply with its mutation cursor
teamleaderleo de81ebd
test: register the restored window before relinking Cloud projections
teamleaderleo 22a62e0
test: wait for the relay ports kick, not the first relay line
teamleaderleo 9d37670
fix(cli): relay output of an SSH session that ends right after auth
teamleaderleo 7b985be
test: restore the no-connection path for rejected vm dev input
teamleaderleo bafd6c3
test: drain the terminal while the SCP host-key failure runs
teamleaderleo a91a26c
Merge #13655 into fix/app-host-green
teamleaderleo f7132b3
Merge #13657 into fix/app-host-green
teamleaderleo 4df563e
test: fail fast when a gated Cloud call ends before its fake is entered
teamleaderleo 49e5dda
test: reveal a retired terminal through the portal rebind, as the app…
teamleaderleo 30590ad
test: pin key-window status in terminal focus suites
teamleaderleo 41d8f87
test: report which layer holds off-plan tmux mirror geometry
teamleaderleo 2f6adcc
Merge #13664 into fix/app-host-green
teamleaderleo ecc8044
fix: restore Cloud projections before the workspace is published
teamleaderleo 8ca302a
test: repair stale and broken app-host expectations
teamleaderleo b102403
Merge remote-tracking branch 'upstream/main' into fix/app-host-green
teamleaderleo 5a92d7f
Merge #13678 into fix/app-host-green
teamleaderleo 87a7016
test: activate the app host before waiting for terminal focus
teamleaderleo a682c55
test: give standalone terminal fixtures a live portal authority
teamleaderleo e28ef70
Merge remote-tracking branch 'origin/main' into fix/app-host-green
teamleaderleo e160e82
chore: normalize project.pbxproj after merging main
teamleaderleo 36f988a
perf(tests): stop app-host unit tests waiting out real timeouts
teamleaderleo 21cca2a
fix: keep the scroll settle default readable from a nonisolated context
teamleaderleo 0af1a5b
fix(tests): stop kicking the port scanner from the poll loop
teamleaderleo cf7eacc
ci: keep the benchmark caller dispatch-only while automatic CI is paused
teamleaderleo 86c850b
fix(tests): model the title-word ranking term in the search reference
teamleaderleo 74cbe2c
fix(tests): drop the ineffective SSH auth retry budget rewrite
teamleaderleo 572f94f
fix(tests): close the persistent CLI client before awaiting the mock
teamleaderleo ed3ab7a
Merge remote-tracking branch 'origin/main' into fix/pr13752-timeout-r…
teamleaderleo 745430d
Retrigger CI after retargeting this PR onto main
teamleaderleo 28d2f72
Make the two new timeout holders instantiable values
teamleaderleo c7e9c55
Remove the KeyStatusTestWindow the main merge declared twice
teamleaderleo a6fd4bf
Merge remote-tracking branch 'origin/main' into fix/pr13752-timeout-r…
teamleaderleo ca1d74d
test: expect the reconnect budget #13959 honors, not the old clamp
teamleaderleo 63a6e26
ci: gate the benchmark runner behind the paid-overflow switch
teamleaderleo 60c4e7b
Merge remote-tracking branch 'origin/main' into fix/pr13752-timeout-r…
teamleaderleo dd779b8
test: close CodeRabbit gaps in the fast app-host test rewrites
teamleaderleo 6e387b0
Keep the Cloud carrier prewarm on activation
teamleaderleo b820391
Merge origin/main into perf/app-host-slow-tests
teamleaderleo 29683cb
test: keep the git fixture's formats when the host sets Git defaults
teamleaderleo 78c6f09
fix: report browser.download.wait's requested timeout as a number again
teamleaderleo 7b3b4b3
test: settle the Global Search palette before each routing test
teamleaderleo 874d9b0
Merge upstream/main into perf/app-host-slow-tests
teamleaderleo 572dc2a
ci: route the palette benchmark workflow to a hosted runner on forks
teamleaderleo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
152 changes: 152 additions & 0 deletions
152
.github/workflows/command-palette-search-benchmarks.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| name: command palette search benchmarks | ||
|
|
||
| # The wall-clock command-palette search benchmarks are gated out of the sharded | ||
| # app-host unit suite by CMUX_COMMAND_PALETTE_SEARCH_BENCHMARKS (see | ||
| # skipUnlessCommandPaletteSearchBenchmarksAreEnabled in | ||
| # cmuxTests/CommandPaletteNucleoFixtures.swift). A gate with no caller at all is | ||
| # deletion with extra steps: the benchmarks keep compiling and stop running. | ||
| # This workflow is that caller -- dispatch-only while automatic CI is paused, so | ||
| # running the benchmarks is a deliberate act rather than a daily cost. It runs | ||
| # the one script that owns the gate, | ||
| # scripts/test-command-palette-nucleo-ffi.sh, which enables the env var and | ||
| # names both benchmark classes; the script's own BENCH assertions fail the job | ||
| # if any gated benchmark silently skipped. | ||
| on: | ||
| # Temporarily manual-only beginning 2026-07-13 to pause automatic CI. | ||
| # tmux-corpus.yml and perf-activation.yml -- the two closest macOS | ||
| # benchmark nightlies -- both carry this and have their crons removed. | ||
| # A new cron here would quietly reverse that reduction, so the gate's | ||
| # caller is dispatch-only until the pause lifts. | ||
| workflow_dispatch: | ||
| inputs: | ||
| runner: | ||
| description: macOS runner (auto follows MACOS_RUNNER_15) | ||
| required: false | ||
| default: auto | ||
| type: choice | ||
| options: | ||
| - auto | ||
| - blacksmith-6vcpu-macos-15 | ||
| - blacksmith-6vcpu-macos-26 | ||
| - blacksmith-6vcpu-macos-latest | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| command-palette-search-benchmarks: | ||
| runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'macos-26' || ((!inputs.runner || inputs.runner == 'auto') && (vars.CI_PAID_MACOS_OVERFLOW == '1' && vars.MACOS_RUNNER_15 || 'blacksmith-6vcpu-macos-15') || inputs.runner)) }} | ||
| timeout-minutes: 60 | ||
| env: | ||
| # XCTest app-host crashes can leave xcodebuild waiting in Swift's crash | ||
| # backtracer until the job timeout. Keep crash handling non-interactive | ||
| # and cheap so xcodebuild can restart/finish the suite. | ||
| SWIFT_BACKTRACE: "interactive=no,timeout=0s,symbolicate=off,color=no" | ||
| # Declared here, not in a step, so the always() summary and upload steps | ||
| # still have a path when an earlier step fails. | ||
| CMUX_NUCLEO_FFI_LOG: ${{ github.workspace }}/command-palette-search-benchmarks.log | ||
| steps: | ||
| - name: Clear stale git locks (self-hosted reused workspace) | ||
| shell: bash | ||
| run: | | ||
| # Self-hosted macOS runners reuse the workspace. A job cancelled or | ||
| # killed mid-checkout can leave a stale .git/modules/*/index.lock that | ||
| # fails every later submodule checkout (e.g. ghostty). Clear them first. | ||
| ws="${GITHUB_WORKSPACE:-$PWD}" | ||
| rm -f "$ws/.git/index.lock" 2>/dev/null || true | ||
| if [ -d "$ws/.git/modules" ]; then | ||
| find "$ws/.git/modules" -type f -name "*.lock" -delete 2>/dev/null || true | ||
| fi | ||
|
|
||
| - name: Checkout | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| persist-credentials: false | ||
| submodules: recursive | ||
|
|
||
| - name: Select Xcode | ||
| run: | | ||
| set -euo pipefail | ||
| ./scripts/select-ci-xcode.sh | ||
|
|
||
| - name: Setup Bun | ||
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | ||
| with: | ||
| bun-version: "1.3.14" | ||
|
|
||
| - name: Cache GhosttyKit.xcframework | ||
| id: cache-ghosttykit | ||
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | ||
| with: | ||
| path: GhosttyKit.xcframework | ||
| key: ghosttykit-sentry-off-v1-${{ hashFiles('.gitmodules', 'ghostty/**') }} | ||
|
|
||
| - name: Download pre-built GhosttyKit.xcframework | ||
| if: steps.cache-ghosttykit.outputs.cache-hit != 'true' | ||
| run: ./scripts/download-prebuilt-ghosttykit.sh | ||
|
|
||
| - name: Install zig | ||
| run: ./scripts/install-zig-ci.sh | ||
|
|
||
| - name: Install Rust | ||
| run: ./scripts/install-rust-ci.sh | ||
|
|
||
| - name: Cache Swift packages | ||
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | ||
| with: | ||
| path: .ci-source-packages | ||
| key: command-palette-bench-spm-${{ hashFiles('cmux.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }} | ||
| restore-keys: command-palette-bench-spm- | ||
|
|
||
| - name: Sanitize Swift package cache | ||
| run: python3 scripts/ci/sanitize-xcode-source-packages-cache.py .ci-source-packages | ||
|
|
||
| - name: Prepare isolated DerivedData | ||
| run: | | ||
| set -euo pipefail | ||
| DERIVED_DATA_PATH="${RUNNER_TEMP}/cmux-derived-data-command-palette-bench-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" | ||
| rm -rf "$DERIVED_DATA_PATH" | ||
| mkdir -p "$DERIVED_DATA_PATH" | ||
| echo "CMUX_NUCLEO_FFI_DERIVED_DATA=$DERIVED_DATA_PATH" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Resolve Swift packages | ||
| run: | | ||
| set -euo pipefail | ||
| SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages" | ||
| mkdir -p "$SOURCE_PACKAGES_DIR" | ||
| xcodebuild -project cmux.xcodeproj -scheme cmux-unit -configuration Debug \ | ||
| -derivedDataPath "$CMUX_NUCLEO_FFI_DERIVED_DATA" \ | ||
| -clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \ | ||
| -resolvePackageDependencies | ||
|
|
||
| - name: Run command palette search benchmarks | ||
| run: | | ||
| set -euo pipefail | ||
| CMUX_NUCLEO_FFI_SOURCE_PACKAGES="$PWD/.ci-source-packages" \ | ||
| ./scripts/test-command-palette-nucleo-ffi.sh | ||
|
|
||
| - name: Write benchmark summary | ||
| if: always() | ||
| run: | | ||
| set -euo pipefail | ||
| { | ||
| echo "## Command palette search benchmarks" | ||
| echo "" | ||
| if [ -f "$CMUX_NUCLEO_FFI_LOG" ]; then | ||
| grep 'BENCH cmd+' "$CMUX_NUCLEO_FFI_LOG" | sed 's/^/- `/; s/$/`/' || echo "No BENCH lines were emitted." | ||
| else | ||
| echo "The benchmark invocation produced no log." | ||
| fi | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: Upload benchmark log | ||
| if: always() | ||
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | ||
| with: | ||
| name: command-palette-search-benchmarks | ||
| path: ${{ env.CMUX_NUCLEO_FFI_LOG }} | ||
| if-no-files-found: ignore | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
...macOS/CmuxControlSocket/Sources/CmuxControlSocket/Policy/BrowserDownloadWaitTimeout.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| public import Foundation | ||
|
|
||
| /// Shared timeout window for the `browser.download.wait` control call. | ||
| /// | ||
| /// The app-side handler and the command-line client have to agree: the client | ||
| /// has to outwait the window the handler is allowed to spend, or a download | ||
| /// that the app reports on time still fails in the terminal. Both sides read | ||
| /// ``standard`` so the two windows cannot drift apart. | ||
| /// | ||
| /// The windows are values rather than fixed constants so a test can hold the | ||
| /// same agreement at a fraction of the wall-clock cost instead of waiting the | ||
| /// shipped window out. | ||
| public struct BrowserDownloadWaitTimeout: Equatable, Sendable { | ||
| /// The windows the app and the CLI ship with. | ||
| public static let standard = BrowserDownloadWaitTimeout() | ||
|
|
||
| /// Window the handler waits when the caller sends no `timeout_ms`. | ||
| public let defaultTimeoutMilliseconds: Int | ||
|
|
||
| /// Ceiling the handler applies to a caller-supplied `timeout_ms`. | ||
| public let maximumTimeoutMilliseconds: Int | ||
|
|
||
| /// Slack the client adds on top of the handler's window to cover request | ||
| /// dispatch, the handler's own bookkeeping, and the reply hop. | ||
| public let clientResponseSlackSeconds: TimeInterval | ||
|
|
||
| /// Creates a window pair the handler and the client both read. | ||
| /// | ||
| /// - Parameters: | ||
| /// - defaultTimeoutMilliseconds: Window for a caller that sends no | ||
| /// `timeout_ms`. | ||
| /// - maximumTimeoutMilliseconds: Ceiling for a caller-supplied | ||
| /// `timeout_ms`. | ||
| /// - clientResponseSlackSeconds: Slack the client adds to the handler's | ||
| /// window. | ||
| public init( | ||
| defaultTimeoutMilliseconds: Int = 10_000, | ||
| maximumTimeoutMilliseconds: Int = 120_000, | ||
| clientResponseSlackSeconds: TimeInterval = 5 | ||
| ) { | ||
| self.defaultTimeoutMilliseconds = defaultTimeoutMilliseconds | ||
| self.maximumTimeoutMilliseconds = maximumTimeoutMilliseconds | ||
| self.clientResponseSlackSeconds = clientResponseSlackSeconds | ||
| } | ||
|
|
||
| /// Window the handler spends for `requestedMilliseconds`. | ||
| /// | ||
| /// - Parameter requestedMilliseconds: The caller's `timeout_ms`, or `nil` | ||
| /// when the caller sent none. | ||
| /// - Returns: The clamped handler window in milliseconds. | ||
| public func handlerTimeoutMilliseconds( | ||
| requestedMilliseconds: Int? | ||
| ) -> Int { | ||
| let requested = max(1, requestedMilliseconds ?? defaultTimeoutMilliseconds) | ||
| return min(requested, maximumTimeoutMilliseconds) | ||
| } | ||
|
|
||
| /// Socket response timeout the client uses for `requestedMilliseconds`. | ||
| /// | ||
| /// - Parameter requestedMilliseconds: The caller's `--timeout-ms`, or `nil` | ||
| /// when the caller passed none. | ||
| /// - Returns: The handler window plus ``clientResponseSlackSeconds``. | ||
| public func clientResponseTimeoutSeconds( | ||
| requestedMilliseconds: Int? | ||
| ) -> TimeInterval { | ||
| let handlerWindow = handlerTimeoutMilliseconds( | ||
| requestedMilliseconds: requestedMilliseconds | ||
| ) | ||
| return TimeInterval(handlerWindow) / 1000.0 + clientResponseSlackSeconds | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
Remove the extra closing parenthesis from
runs-on.The expression ends with
inputs.runner)), but only one closing parenthesis is needed there. The supplied actionlint failure confirms that the expression cannot parse. As a result, the dispatch-only benchmark workflow cannot run. Change the ending toinputs.runner) }}and rerun actionlint. (docs.github.com)🧰 Tools
🪛 GitHub Actions: Testbox broker guard / 0_Testbox broker trust boundary.txt
[error] 42-42: actionlint failed: parser did not reach end of input after parsing the expression; an extra ")" remains in the runs-on expression. The actionlint command exited with code 1.
🪛 GitHub Actions: Testbox broker guard / Testbox broker trust boundary
[error] 42-42: actionlint failed to parse the GitHub Actions expression: an extra closing parenthesis remains at the end of the expression. CI command: "$RUNNER_TEMP/actionlint".
🤖 Prompt for AI Agents
Source: Pipeline failures