Skip to content

fix(mcp): enforce wall-clock timeout for test runs - #1766

Merged
erickzanardo merged 6 commits into
mainfrom
vgv-ai-bot/issue-1765
Oct 23, 2026
Merged

erickzanardo merged 6 commits into
mainfrom
vgv-ai-bot/issue-1765

Conversation

@unicoderbot

@unicoderbot unicoderbot Bot commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #1765

Summary

The MCP test tool's timeout_seconds parameter was forwarded as --timeout to flutter test, which implements a per-test timeout that doesn't fire when a test awaits a future that never completes (e.g., in tester.runAsync). This caused hung tests to block the MCP server indefinitely since tool runs are serialized with a lock.

Changes

  • Wall-clock timeout enforcement: timeout_seconds is now enforced as a hard limit on the entire tool run in _runToolCommand using Future.timeout. When exceeded, the tool immediately returns a timeout failure, releasing the server lock so queued calls can proceed.

  • Removed per-test timeout flag: The --timeout flag is no longer forwarded to the test command since it doesn't address the documented use case (hanging in async operations).

  • Updated documentation: Clarified that timeout_seconds is a wall-clock budget, not a per-test timeout, and explained how it bounds hangs that bypass the test runner's timeout.

  • New failure type: Added ToolFailureType.timeout to distinguish timeout failures from other errors, with appropriate recovery guidance.

  • Tests: Added comprehensive tests verifying that:

    • Timeout failures are returned when the budget elapses
    • The server lock is released so queued calls proceed
    • Commands complete normally when no timeout is specified

This ensures that a single hung test cannot stall all other tool calls on the MCP server.

Closes #1765

Co-authored-by: ryzizub <ryzizub@users.noreply.github.com>
erickzanardo
erickzanardo previously approved these changes Oct 14, 2026
@ryzizub

ryzizub commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

@vgvbot two changes before this can merge.

1. Kill the run, don't just abandon it. After the budget elapses very_good test keeps running in-process and the flutter_tester process stays alive, so every timeout leaks a hung process — the issue asked for the process tree to be killed.

There is a path for it: very_good_test_runner kills the process when its stream subscription is cancelled, and _testCommand in lib/src/cli/test_cli_runner.dart already listens to an injectable SIGINT stream via ProcessSignalOverrides.runZoned. Run the command inside that zone and emit SIGINT when the budget elapses. Note its SIGINT branch completes with ExitCode.success today, so a timeout must stay distinguishable from a clean cancel.

2. Directory.current race. _runToolCommand restores the previous directory in finally while the abandoned run can still spawn subprocesses, so the next queued call and the abandoned one now share a process-global that the lock used to protect. Fixing (1) removes this.

@unicoderbot

unicoderbot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

On it, I'll address the review comments and push the changes.

  • Preparing environment
    • Cloning repository
    • Setting up dev environment
  • Reviewing feedback
  • Working on changes
  • Pushing updates

I've pushed changes to address the feedback.

Co-authored-by: ryzizub <ryzizub@users.noreply.github.com>
Comment thread lib/src/mcp/mcp_server.dart
Comment thread lib/src/mcp/tool_run.dart Outdated
@erickzanardo

Copy link
Copy Markdown
Member

/unicoder address the comments on the PR

@unicoderbot

unicoderbot Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

On it, I'll address the review comments and push the changes.

  • Preparing environment
    • Cloning repository
    • Setting up dev environment
  • Reviewing feedback
  • Working on changes
  • Pushing updates

I've pushed changes to address the feedback.

Co-authored-by: erickzanardo <erickzanardo@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

📊 Cognitive Complexity Analysis

Net Delta: +5 | Added: 2 | Increased: 3 | Improved: 2 | Removed: 0 | Violations: 0

Status Declaration Location Delta Score
🟡 _runCommand lib/src/cli/flutter_cli.dart:L226-257 +2 6 -> 8
🟡 _testCommand lib/src/cli/test_cli_runner.dart:L377-450 +1 7 -> 8
🔵 _Cmd.sortedPubspecs lib/src/cli/cli.dart:L135-162 +3 new -> 3
🔵 VeryGoodMCPServer._runWithOptionalTimeout lib/src/mcp/mcp_server.dart:L599-631 +2 new -> 2
🟢 VeryGoodMCPServer._parseTest lib/src/mcp/mcp_server.dart:L394-435 -1 3 -> 2
🟡 VeryGoodMCPServer._handleTest lib/src/mcp/mcp_server.dart:L486-499 +1 0 -> 1
🟢 _Cmd.runWhere lib/src/cli/cli.dart:L127-133 -3 3 -> 0

Comment thread lib/src/cli/flutter_cli.dart
@erickzanardo

Copy link
Copy Markdown
Member

/unicoder address the last comment on the PR

@unicoderbot

unicoderbot Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

On it, I'll address the review comments and push the changes.

  • Preparing environment
    • Cloning repository
    • Setting up dev environment
  • Reviewing feedback
  • Working on changes
  • Pushing updates

I've pushed changes to address the feedback.

unicoderbot Bot and others added 2 commits October 23, 2026 17:39
Co-authored-by: erickzanardo <erickzanardo@users.noreply.github.com>
@erickzanardo
erickzanardo enabled auto-merge (squash) October 23, 2026 17:46
@erickzanardo
erickzanardo merged commit a2ec7d8 into main Oct 23, 2026
26 checks passed
@erickzanardo
erickzanardo deleted the vgv-ai-bot/issue-1765 branch October 23, 2026 17:46
@vgvbot vgvbot mentioned this pull request Oct 23, 2026
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(mcp): test timeout_seconds does not kill a hung test run, which blocks every later tool call

3 participants