Analysis of commit 6a63c3b (introduced primarily in a7ea9ab "Authorize extension pipes for sandboxed test hosts", #10842)
Assignee: @copilot
Summary
HangDumpProcessLifetimeHandler.BeforeTestHostProcessStartAsync and TrxProcessLifetimeHandler.BeforeTestHostProcessStartCore contain a byte-for-byte identical 10-line block that constructs the NamedPipeServer from a NamedPipeServerEndpoint, wires up authorized security identities, and writes the resolved pipe name back onto the shared endpoint. The surrounding constructor fields (_serviceProvider, _endpoint) and the pattern used to create the initial NamedPipeServerEndpoint in the corresponding *Extensions.cs registration methods are also structurally duplicated.
Duplication Details
Pattern: NamedPipeServer construction + endpoint pipe-name write-back
- Severity: Medium
- Occurrences: 2 exact instances (constructor body), plus 2 structurally-identical endpoint-creation call sites in the corresponding extension registration files (4 total similar sites)
- Locations:
src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs (lines 171-180)
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs (lines 132-141)
src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpExtensions.cs (endpoint creation: new NamedPipeServerEndpoint(NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")).Name))
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportExtensions.cs (identical endpoint creation line)
- Code Sample:
_singleConnectionNamedPipeServer = new(
new PipeNameDescription(_endpoint.PipeName),
CallbackAsync,
_environment,
_logger,
_task,
maxNumberOfServerInstances: 1,
_serviceProvider.GetTestHostControllerAuthorizedSecurityIdentities(),
cancellationToken);
_endpoint.PipeName = _singleConnectionNamedPipeServer.PipeName.Name;
This exact block appears in both HangDumpProcessLifetimeHandler.cs and TrxProcessLifetimeHandler.cs, differing only in the CallbackAsync target's containing type.
Impact Analysis
- Maintainability: Any future change to how the pipe server is constructed for sandboxed authorization (e.g., additional security identity sources, extra pipe options) must be manually applied in both handlers, risking drift.
- Bug Risk: This code already changed once (from a plain
PipeNameDescription to the new NamedPipeServerEndpoint + authorized-identities model) across both files in the same PR — a clear sign the logic is coupled and should be centralized to avoid inconsistent future edits.
- Code Bloat: Minor, but the duplication will grow if a third extension (e.g., a future sandboxed extension) copies the same pattern again, as already happened with
RetryFailedTestsPipeServer.cs and HangDumpExtensions.cs/TrxReportExtensions.cs sharing the NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")) idiom.
Refactoring Recommendations
-
Extract a shared helper for authorized single-connection pipe server creation
- Extract common functionality to:
src/Platform/Microsoft.Testing.Platform/TestHostControllers/NamedPipeServerEndpoint.cs (or a new small internal static helper, e.g. AuthorizedNamedPipeServerFactory) exposing something like:
internal static NamedPipeServer CreateAndBind(
NamedPipeServerEndpoint endpoint,
Func<IRequest, Task<IResponse>> callback,
IEnvironment environment,
ILogger logger,
ITask task,
IServiceProvider serviceProvider,
CancellationToken cancellationToken)
which performs the new PipeNameDescription(...), NamedPipeServer construction with maxNumberOfServerInstances: 1 and GetTestHostControllerAuthorizedSecurityIdentities(), and the endpoint.PipeName = ... write-back in one place.
- Estimated effort: ~2-3 hours including unit test updates.
- Benefits: Single source of truth for the sandboxed-authorization wiring; future extensions (or a third handler) can reuse it without copy-paste; reduces risk of one handler missing the authorized-identities fix.
-
Factor out the endpoint bootstrap line in the *Extensions.cs registration methods
- Both
HangDumpExtensions.AddHangDumpProvider and TrxReportExtensions.ControllerBackedRegistrations build the initial endpoint via new NamedPipeServerEndpoint(NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")).Name). Extract this into a small factory method (e.g., NamedPipeServerEndpoint.CreateWithNewPipeName()) on NamedPipeServerEndpoint itself.
- Estimated effort: ~30 minutes.
- Benefits: Removes the repeated
Guid.NewGuid().ToString("N") idiom from two call sites and keeps endpoint creation logic co-located with the type it constructs.
Implementation Checklist
Analysis Metadata
- Analyzed Files: ~30 files changed across last ~8 commits (HangDump, TrxReport, Retry, PackagedApp, and Performance test areas)
- Detection Method: Semantic code analysis (git diff review + structural comparison)
- Commit: 6a63c3b
- Analysis Date: 2026-08-29
🤖 Automated content by GitHub Copilot. Generated by the Duplicate Code Detector workflow. · auto · 39.5 AIC · ⌖ 1.67 AIC · ⊞ 12.9K · [◷]( · ◷)
Add this agentic workflow to your repo
To install this agentic workflow, run
gh aw add githubnext/agentics/workflows/duplicate-code-detector.md@main
Analysis of commit 6a63c3b (introduced primarily in a7ea9ab "Authorize extension pipes for sandboxed test hosts", #10842)
Assignee:
@copilotSummary
HangDumpProcessLifetimeHandler.BeforeTestHostProcessStartAsyncandTrxProcessLifetimeHandler.BeforeTestHostProcessStartCorecontain a byte-for-byte identical 10-line block that constructs theNamedPipeServerfrom aNamedPipeServerEndpoint, wires up authorized security identities, and writes the resolved pipe name back onto the shared endpoint. The surrounding constructor fields (_serviceProvider,_endpoint) and the pattern used to create the initialNamedPipeServerEndpointin the corresponding*Extensions.csregistration methods are also structurally duplicated.Duplication Details
Pattern:
NamedPipeServerconstruction + endpoint pipe-name write-backsrc/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs(lines 171-180)src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs(lines 132-141)src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpExtensions.cs(endpoint creation:new NamedPipeServerEndpoint(NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")).Name))src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportExtensions.cs(identical endpoint creation line)HangDumpProcessLifetimeHandler.csandTrxProcessLifetimeHandler.cs, differing only in theCallbackAsynctarget's containing type.Impact Analysis
PipeNameDescriptionto the newNamedPipeServerEndpoint+ authorized-identities model) across both files in the same PR — a clear sign the logic is coupled and should be centralized to avoid inconsistent future edits.RetryFailedTestsPipeServer.csandHangDumpExtensions.cs/TrxReportExtensions.cssharing theNamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N"))idiom.Refactoring Recommendations
Extract a shared helper for authorized single-connection pipe server creation
src/Platform/Microsoft.Testing.Platform/TestHostControllers/NamedPipeServerEndpoint.cs(or a new small internal static helper, e.g.AuthorizedNamedPipeServerFactory) exposing something like:new PipeNameDescription(...),NamedPipeServerconstruction withmaxNumberOfServerInstances: 1andGetTestHostControllerAuthorizedSecurityIdentities(), and theendpoint.PipeName = ...write-back in one place.Factor out the endpoint bootstrap line in the
*Extensions.csregistration methodsHangDumpExtensions.AddHangDumpProviderandTrxReportExtensions.ControllerBackedRegistrationsbuild the initial endpoint vianew NamedPipeServerEndpoint(NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")).Name). Extract this into a small factory method (e.g.,NamedPipeServerEndpoint.CreateWithNewPipeName()) onNamedPipeServerEndpointitself.Guid.NewGuid().ToString("N")idiom from two call sites and keeps endpoint creation logic co-located with the type it constructs.Implementation Checklist
Analysis Metadata
Add this agentic workflow to your repo
To install this agentic workflow, run