Fix test runner silent failure on dual-stack IPv4/IPv6 systems#3953
Merged
rafaelfranca merged 3 commits intomainfrom Feb 13, 2026
Merged
Fix test runner silent failure on dual-stack IPv4/IPv6 systems#3953rafaelfranca merged 3 commits intomainfrom
rafaelfranca merged 3 commits intomainfrom
Conversation
Copilot
AI
changed the title
[WIP] Fix test runner silent failure with IPv6 support
Fix test runner silent failure on dual-stack IPv4/IPv6 systems
Feb 11, 2026
aa949ef to
00b33af
Compare
00b33af to
27801a0
Compare
rafaelfranca
approved these changes
Feb 11, 2026
83873db to
9c98b39
Compare
vinistock
requested changes
Feb 13, 2026
61ae0b7 to
f09d73c
Compare
vinistock
approved these changes
Feb 13, 2026
- Connect directly to 127.0.0.1 instead of trying multiple address families - This matches the VS Code extension which listens on IPv4 (127.0.0.1) only - Simpler implementation that avoids unnecessary IPv6 connection attempts Avoiding having to mess with the singleton instance variable in tests Instead just creating a new instance of the reporter for each test. This is simpler and avoids some of the weird edge cases around resetting the singleton state between tests. Fixes #3868.
This method doesn't need any information from the instance, so we can move it to the class level and avoid having to call it through the singleton and avoid the TCP connection to intialize the singleton in the test.
f09d73c to
7bb13d7
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
On systems where
localhostresolves to both IPv6 (::1) and IPv4 (127.0.0.1), test runs hang indefinitely without error indication. The Ruby client connects to whichever address the system resolver returns first (typically IPv6), while the VS Code extension may only listen on IPv4. Connection failures were silently swallowed by a barerescueblock.Implementation
Ruby LSP Reporter (
lib/ruby_lsp/test_reporters/lsp_reporter.rb):127.0.0.1explicitly instead oflocalhosthostnameStringIOVS Code Extension (
vscode/src/streamingRunner.ts):127.0.0.1explicitly instead oflocalhosthostnameBoth client and server now use IPv4 explicitly, eliminating address family mismatches. The fix is minimal—changing hostname strings rather than implementing complex dual-stack logic.
Automated Tests
Added two tests to
test/test_reporters/lsp_reporter_test.rb:test_socket_connects_to_ipv4_explicitly- Verifies successful IPv4 connectiontest_socket_uses_ipv4_address_not_localhost- Verifies AF_INET address familyManual Tests
On a system with both IPv4 and IPv6 support:
Original prompt
This section details on the original issue you should resolve
<issue_title>Test runner fails silently when IPv6 is supported</issue_title>
<issue_description>### Description
I found that
LSPReporter's creation of theTCPSocketonly attempts to connect to IPv6. On my machine,localhostresolves to both.DNS resolution details
> dscacheutil -q host -a name localhost name: localhost ipv6_address: ::1 name: localhost ip_address: 127.0.0.1The Ruby
TCPSocketclient should optimally attempt to connect to both addresses returned by resolution. I'm not sure why it doesn't.But the other cause of this is the VSCode extension is only listening on IPv4. This seems to be true of other VSCode extensions, so this might be configuration that VSCode sets.
In my listening ports, most other processes listen on both IPv6 and IPv4 localhost. Only VSCode seems to fail in this respect.
lsof output
Next, the connection failure is swallowed by the rescue block which instantiates a
StringIO. This causes a silent failure without logging any hint as to the issue, because writes to theStringIOgo nowhere.Finally, the extension never times out on a test run. Telling the extension to restart the LSP server doesn't end the waiting state either. The extension host must be restarted to be able to start another test run. This seems like it would also affect other failures of the test runner, for example if it crashes without sending the "finish" message.
Ruby LSP Information
VS Code Version
(Cursor Version: 2.2.20)
VSCode 1.105.1
MacOS 15.7.2
Also reproduced in VSCode 1.107.0
Ruby LSP Extension Version
0.9.32
Ruby LSP Server Version
0.26.4
Ruby LSP Add-ons
Ruby Version
3.3.1
Ruby Version Manager
rbenv
Installed Extensions
Click to expand
Ruby LSP Settings
Click to expand
Workspace
{}User
{ "enabledFeatures": { "codeActions": true, "diagnostics": true, "documentHighlights": true, "documentLink": true, "documentSymbols": true, "foldingRanges": true, "formatting": true, "hover": true, ... </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes Shopify/ruby-lsp#3868 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.