Skip to content

[duplicate-code] Duplicate Code: NamedPipeServer construction/endpoint pattern in HangDump & TrxReport lifetime handlers #10855

Description

@github-actions

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

  1. 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.
  2. 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

  • Review duplication findings
  • Prioritize refactoring tasks
  • Create refactoring plan
  • Implement changes
  • Update tests
  • Verify no functionality broken

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
  • expires on Aug 31, 2026, 4:26 AM UTC

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/automationCreated or maintained by an agentic workflow.type/tech-debtCode health, refactoring, simplification.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions