Skip to content

[file-diet] Refactor ServerTestHost.cs into focused partial-class files (795 lines) #8864

@Evangelink

Description

@Evangelink

Overview

The file src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs has grown to 795 lines, making it harder to navigate and maintain. The class is already declared as partial, which makes splitting it into focused partial-class files a natural and low-risk refactoring.

Current State

  • File: src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs
  • Size: 795 lines
  • Language: C#
Structural Analysis

The file contains a single internal sealed partial class ServerTestHost with the following distinct concern groups:

Lines Concern
57–100 Constructor, field declarations, and identity properties (Uid, Version, DisplayName, Description)
101–186 Unhandled-exception handlers (OnCurrentDomainUnhandledException, OnTaskSchedulerUnobservedTaskException) and the top-level InternalRunAsync entry point
188–276 Main server message loop (HandleMessagesAsync) — reads messages from the transport and fans them out
278–411 Inbound request/notification dispatching (HandleNotificationAsync, HandleRequestAsync, CompleteRequest)
412–637 Per-request test execution, metrics, and telemetry (HandleRequestCoreAsync, ExecuteRequestAsync, GetDiscoveryMetrics, GetRunMetrics)
639–733 Outbound messaging helpers (SendErrorAsync, SendResponseAsync, SendMessageAsync, SendTestUpdateCompleteAsync, SendTestUpdateAsync, SendTelemetryEventUpdateAsync, PushDataAsync)
737–794 Private nested helper class RpcInvocationState (cancellable invocation state machine)

Refactoring Strategy

Because ServerTestHost is already declared partial, each split is purely additive — no imports, project files, or callers need to change.

Proposed File Splits

  1. ServerTestHost.cs (trimmed)

    • Contents: field declarations, constructor, identity properties (Uid, Version, DisplayName, Description, IsInitialized, AssertInitialized), InternalRunAsync, Dispose, exception handlers
    • Responsibility: Core host lifecycle and state
  2. ServerTestHost.MessageLoop.cs (new partial)

    • Contents: HandleMessagesAsync, HandleNotificationAsync, HandleRequestAsync, CompleteRequest, nested RpcInvocationState
    • Responsibility: Reading and dispatching inbound JSON-RPC messages
  3. ServerTestHost.RequestExecution.cs (new partial)

    • Contents: HandleRequestCoreAsync, ExecuteRequestAsync, GetDiscoveryMetrics, GetRunMetrics
    • Responsibility: Per-request test-run / discovery execution and telemetry metrics
  4. ServerTestHost.Messaging.cs (new partial)

    • Contents: SendErrorAsync, SendResponseAsync, SendMessageAsync, SendTestUpdateCompleteAsync, SendTestUpdateAsync, SendTelemetryEventUpdateAsync, PushDataAsync
    • Responsibility: Sending outbound JSON-RPC messages and notifications

Implementation Guidelines

  1. Preserve Behavior: All existing functionality must work identically after the split
  2. Maintain Public API: Keep all public/internal symbols accessible with the same names
  3. No new using directives needed: All partial files share the same namespace; group the using directives by file
  4. Test After Each Split: Run unit tests after each incremental partial-class extraction
  5. One File at a Time: Extract one logical group at a time to make code review easier

Acceptance Criteria

  • Original file is split into focused partial-class files
  • Each new file is under 300 lines
  • All tests pass after refactoring (./build.sh -test)
  • No breaking changes to public or internal API
  • Each partial file has a single, clearly stated responsibility

Priority: Medium
Effort: Small (pure code movement — no logic changes required)
Expected Impact: Improved code navigability, easier per-concern reviews, reduced merge conflicts on the host layer

Generated by Daily File Diet · sonnet46 1M ·

  • expires on Jun 7, 2026, 7:31 PM UTC

Metadata

Metadata

Labels

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

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions