Skip to content

Allow IPC named pipe directory to be overridden on Unix#9846

Merged
Evangelink merged 10 commits into
mainfrom
dev/amauryleve/improved-train
Jul 13, 2026
Merged

Allow IPC named pipe directory to be overridden on Unix#9846
Evangelink merged 10 commits into
mainfrom
dev/amauryleve/improved-train

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Fixes #9821

Problem

On Unix, the Microsoft.Testing.Platform IPC named pipe is backed by a Unix domain socket file on disk, and NamedPipeServer.GetPipeName hardcoded that file to live under /tmp. In sandboxed environments that block /tmp (the reporter hit this with Claude Code on macOS), dotnet test fails and the only workaround is to open up the whole /tmp folder to the sandbox.

Change

On Unix, the pipe directory is now resolved with this precedence:

  1. TESTINGPLATFORM_PIPE_DIRECTORY — new explicit opt-in override (guaranteed escape hatch).
  2. Path.GetTempPath() — honors TMPDIR on Unix, which is the standard POSIX knob and is usually a per-user, sandbox-allowed directory (so many setups are fixed with no extra configuration).
  3. /tmp — preserves the previous default when neither is set.

Windows is unchanged (it uses the kernel pipe namespace, not the filesystem).

Guards

Because the location is now user-influenced:

  • Path length (always): Unix domain socket paths are capped by sun_path (~104 bytes on macOS, ~108 on Linux). We validate against the smaller 103-byte budget and fail with an actionable, localized message. This matters most for a deep TMPDIR on macOS (/var/folders/…/T/ + a GUID).
  • Writability (override only): when the explicit override is used we create the directory if needed and probe write access with a short-lived file, failing fast with a clear message instead of a cryptic socket bind error. TMPDIR//tmp are OS-managed and skipped to avoid extra I/O and a behavior change on every pipe creation.

Compatibility notes

The design deliberately keeps the existing invariant: the process that creates the pipe resolves the directory locally and hands the fully-resolved path to the peer (via env var, command-line arg, or the dotnet-test handshake); peers use that path verbatim and never recompute it. As a result:

  • No protocol version bump is needed — a TESTINGPLATFORM_PIPE_DIRECTORY/TMPDIR difference between two processes is harmless because only the creator's resolution is ever used.
  • The logic is self-contained in NamedPipeServer.cs, which dotnet/sdk vendors, so the dotnet test entrypoint picks this up on the next vendor sync with no separate SDK design work.

An XML-doc note on GetPipeName captures this invariant so the directory is never turned into a shared convention that both sides derive independently (which would couple SDK and test-host versions).

Localization

Two new strings added to PlatformResources.resx with hand-maintained accessors in the !IS_CORE_MTP block; .xlf regenerated for all 14 languages via UpdateXlf.

Tests

Added 8 MSTest cases in IPCTests.cs covering override precedence, TMPDIR fallback, /tmp fallback, and the length guard (within/exceeds). Resolution and length-check logic was split into internal seams so they are testable on Windows CI, where the Unix branch of GetPipeName never runs. Full IPCTests class passes locally (net8.0).

On Unix the IPC named pipe is backed by a Unix domain socket file that was
always created under /tmp. Sandboxed environments (e.g. Claude Code on macOS)
that block /tmp cannot run `dotnet test`. Resolve the directory as:

  1. TESTINGPLATFORM_PIPE_DIRECTORY (explicit opt-in override)
  2. Path.GetTempPath() (honors TMPDIR on Unix)
  3. /tmp (previous default)

Add a sun_path length guard (always) and a writability probe (override only),
both failing with actionable, localized messages. Keep the logic self-contained
in NamedPipeServer.cs so it flows into dotnet/sdk on the next vendor sync, and
document the "creator resolves, full path is passed, peers never recompute"
invariant so the directory never becomes a shared convention that couples SDK
and test-host versions.

Fixes #9821

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae434eba-3cad-4c61-a1da-ef252ae87f48
Copilot AI review requested due to automatic review settings July 11, 2026 12:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds configurable Unix IPC socket directories for sandbox compatibility while preserving Windows behavior.

Changes:

  • Adds override/temp-directory resolution and safety guards.
  • Adds localized diagnostics and environment-variable support.
  • Adds unit tests and regenerated localization files.
Show a summary per file
File Description
test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs Tests directory resolution and path-length limits.
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs Implements Unix pipe-directory selection and validation.
src/Platform/Microsoft.Testing.Platform/Helpers/EnvironmentVariableConstants.cs Defines the pipe-directory override variable.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.cs Adds resource accessors.
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx Adds localized diagnostic source strings.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf Updates Czech localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf Updates German localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf Updates Spanish localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf Updates French localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf Updates Italian localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf Updates Japanese localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf Updates Korean localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf Updates Polish localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf Updates Brazilian Portuguese localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf Updates Russian localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf Updates Turkish localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf Updates Simplified Chinese localization.
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf Updates Traditional Chinese localization.

Review details

  • Files reviewed: 18/18 changed files
  • Comments generated: 6
  • Review effort level: Medium

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@github-actions

This comment has been minimized.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Review Summary

Overall: Solid, well-motivated change. The design is sound — the single-resolver invariant (creator resolves, peer uses verbatim) is the right architecture and the XML doc captures it well. The guards (path length + writability probe) are practical and the error messages are actionable.

Findings by severity

Severity Dimension Finding
MAJOR Test Completeness (#13) EnsureDirectoryIsWritable has no unit tests — it has meaningful branching worth covering
MODERATE Data-Driven (#14) Missing " " (whitespace) [DataRow] for tempPath in the /tmp fallback test
NIT Algorithmic (#1) The /tmp fallback in ResolvePipeDirectory is effectively dead code in production (only reachable via the testable overload) — worth a clarifying comment
NIT Security (#3) Consider Path.GetFullPath() normalization on the explicit override for path hygiene

Dimensions checked and clean

✅ Threading & Concurrency — no shared mutable state; all new methods are static/pure or local I/O
✅ Public API — class is internal [Embedded]; constants are public on an internal class (effectively internal); no PublicAPI.Unshipped.txt update needed
✅ IPC Wire Compatibility — no wire format changes; directory resolution is local-only
✅ Performance — GetPipeName is not a hot path; probe I/O only on explicit override
✅ Resource/IDisposable — probe file uses using + File.Delete
✅ Localization — .resx entries added correctly; .xlf regenerated; accessors placed in the !IS_CORE_MTP block (correct — these are needed by extension projects that link the file)
✅ Naming & Conventions — test names describe scenario and outcome
✅ Scope & PR Discipline — focused change, no unrelated refactoring
✅ Build Infrastructure — no dependency changes

No blocking issues found.

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs
Comment thread test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@github-actions

This comment has been minimized.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Build Failure Analysis workflow. · 61.6 AIC · ⌖ 4.9 AIC · ⊞ 7.3K ·

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs Outdated
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs Outdated
…ests

- Replace banned System.Environment / string.IsNullOrWhiteSpace with
  SystemEnvironment / RoslynString to fix RS0030.
- Declare the four new internal symbols in InternalAPI.Unshipped.txt (RS0016).
- Normalize an explicit override with Path.GetFullPath so a relative
  TESTINGPLATFORM_PIPE_DIRECTORY resolves to a rooted socket path and honors
  the "full path handed to peers" invariant (also collapses '..').
- Clarify that the '/tmp' fallback is only reachable via the test overload.
- Add unit tests for EnsureDirectoryIsWritable (create-missing happy path and
  non-creatable error path) and a whitespace DataRow for the tempPath fallback.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae434eba-3cad-4c61-a1da-ef252ae87f48
Copilot AI review requested due to automatic review settings July 11, 2026 12:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs Outdated
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@github-actions

This comment has been minimized.

…ed-train

# Conflicts:
#	src/Platform/Microsoft.Testing.Platform/InternalAPI/InternalAPI.Unshipped.txt
Copilot AI review requested due to automatic review settings July 11, 2026 12:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 19/19 changed files
  • Comments generated: 4
  • Review effort level: Medium

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@github-actions

This comment has been minimized.

NamedPipeServer.cs is glob-compiled (IPC\*.cs) into HangDump, Retry,
TrxReport, and both MSBuild projects, so the earlier fixes must build there:

- Read TESTINGPLATFORM_PIPE_DIRECTORY via System.Environment with a scoped
  RS0030 suppression instead of `new SystemEnvironment()`. Only the MSBuild
  task project links SystemEnvironment.cs; the other shared-source consumers
  do not, so the wrapper would not compile there. Reading directly also keeps
  the file self-contained for the dotnet/sdk vendor copy.
- Normalize the selected directory with Path.GetFullPath in every precedence
  branch (not just the explicit override): Path.GetTempPath() can surface a
  relative TMPDIR, which NamedPipeServerStream rejects and which would violate
  the fully-resolved-path invariant. The write probe stays override-only.
- Declare the new EnvironmentVariableConstants / NamedPipeServer /
  PlatformResources members in the HangDump, Retry, TrxReport, and
  Extensions.MSBuild InternalAPI.Unshipped baselines (they compile these shared
  files and keep their baselines in sync with core), so RS0016 stays green.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae434eba-3cad-4c61-a1da-ef252ae87f48
Copilot AI review requested due to automatic review settings July 11, 2026 13:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 23/23 changed files
  • Comments generated: 2
  • Review effort level: Medium

…consumers

The earlier baseline update missed some projects that link the shared files:

- EnvironmentVariableConstants.cs is also linked into HotReload -> add the new
  TESTINGPLATFORM_PIPE_DIRECTORY const there.
- PlatformResources.cs (the !IS_CORE_MTP accessors) is linked into nine
  API-tracked extensions -> add the two new NamedPipe* accessor signatures to
  HtmlReport, CtrfReport, JUnitReport, VideoRecorder, and CrashDump (the other
  four were done previously).

Verified each affected project builds clean with
-warnaserror:RS0016,RS0017,RS0025,RS0037.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae434eba-3cad-4c61-a1da-ef252ae87f48
Copilot AI review requested due to automatic review settings July 11, 2026 13:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment thread src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx Outdated
Comment thread src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx Outdated
@github-actions

This comment has been minimized.

@Evangelink Evangelink added the state/needs-review Awaiting review from the team. label Jul 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs
Copilot AI review requested due to automatic review settings July 11, 2026 20:52
@Evangelink
Evangelink enabled auto-merge (squash) July 11, 2026 20:52
…unting

The existing path-length tests used only ASCII, so a buggy character-count
implementation would still pass. Add a test with 40 '好' (3-byte) chars plus a
prefix: 45 characters (under the 103 limit) but 125 UTF-8 bytes (over it),
proving the guard measures sun_path bytes rather than characters.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae434eba-3cad-4c61-a1da-ef252ae87f48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

Copilot AI review requested due to automatic review settings July 11, 2026 20:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@github-actions

This comment has been minimized.

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
Copilot AI review requested due to automatic review settings July 13, 2026 08:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

❌ Build Failure Analysis

Project: Microsoft.Testing.Platform.UnitTests
Root cause: MSTEST0037 analyzer errors — Assert.IsTrue used for relational comparisons instead of the dedicated assertion APIs.

Errors (4 total, 2 unique locations)

File Line Message
IPCTests.cs 119 Use Assert.IsLessThan instead of Assert.IsTrue
IPCTests.cs 120 Use Assert.IsGreaterThan instead of Assert.IsTrue

The errors appear twice because the project targets two frameworks (both evaluations fail).

Fix

Replace the Assert.IsTrue relational checks on lines 119–120 with Assert.IsLessThan / Assert.IsGreaterThan. See inline suggestions below.

🤖 Automated content by GitHub Copilot. Generated by the Build Failure Analysis workflow. · 70.5 AIC · ⌖ 5.18 AIC · ⊞ 7.4K · [◷]( · )

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Automated content by GitHub Copilot. Generated by the Build Failure Analysis workflow. · 70.5 AIC · ⌖ 5.18 AIC · ⊞ 7.4K ·

Comment thread test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs Outdated
Comment thread test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs Outdated
Replace Assert.IsTrue(a < b)/Assert.IsTrue(a > b) with Assert.IsLessThan /
Assert.IsGreaterThan in the multibyte path-length setup assertions. Note the
argument order is (bound, value) - the raw analyzer codefix suggestion had the
operands reversed, which would have inverted the assertions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae434eba-3cad-4c61-a1da-ef252ae87f48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9846

GradeTestNotes
A (90–100) new IPCTests.
EnsurePathLengthWithinLimit_
WhenMultibyteExceedsByteLimitButNotCharLimit_
Throws
Clear AAA structure; precondition assertions guard test-setup validity, and ThrowsExactly(InvalidOperationException) precisely pins the exception type.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 38.4 AIC · ⌖ 6.04 AIC · ⊞ 8.9K · [◷]( · )

@Evangelink
Evangelink merged commit 944a886 into main Jul 13, 2026
81 checks passed
@Evangelink
Evangelink deleted the dev/amauryleve/improved-train branch July 13, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-review Awaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow IPC named pipe directory to be overridden via environment variable

4 participants