ITADN

[file-diet] Refactor TestHostControllersTestHost.cs (641 lines) into smaller, focused files

#10512Opengithub-actions[bot] 创建于 16 天前
type/tech-debttype/automation
### Overview The file `src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs` has grown to 641 lines, making it harder to navigate and maintain. This task involves refactoring it into smaller, more focused files. ### Current State - **File**: `src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs` - **Size**: 641 lines - **Language**: C# <details> <summary><b>Structural Analysis</b></summary> The class `TestHostControllersTestHost` (internal sealed, implements `CommonHost`, `IHost`, `IDisposable`, `IOutputDeviceDataProducer`) contains: - `InternalRunAsync` (lines 72–466, ~395 lines) — a single monolithic method that: - Resolves services and builds the test host process command line/environment variables - Applies `ITestHostEnvironmentVariableProvider` extensions and validates environment variables - Fires `ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync` - Launches the test host process (default or custom launcher) - Sets up the named-pipe IPC server and waits for the test host PID handshake - Fires `OnTestHostProcessStartedAsync` / waits for process exit / handles cancellation-triggered termination - Fires `OnTestHostProcessExitedAsync`, drains/disables the message bus - Applies coverage threshold checks and computes the final exit code - Collects telemetry/extension information and logs the final result - `LaunchUsingCustomLauncherAsync` (lines 467–508) — launches the process via a custom `ITestHostLauncher` - `GetAuthorizedSecurityIdentitiesAsync` (lines 509–556) — resolves security identities for the IPC server - `DisposeServicesAsync` (lines 557–610) — disposes services in the provider - `HandleRequestAsync` (lines 611–638) — handles inbound IPC requests (PID/exit-code messages) - `Dispose` (line 639+) The bulk of the size and complexity lives in the single `InternalRunAsync` method, which mixes several distinct concerns (environment variable setup, process launch, IPC handshake, lifetime-handler notification, exit/coverage handling, cleanup) in one long procedural block. </details> ### Refactoring Strategy #### Proposed File Splits 1. **`TestHostControllersTestHost.EnvironmentSetup.cs`** *(partial class)* - Contents: environment-variable preparation logic currently inline in `InternalRunAsync` (building `partialCommandLine`, `ProcessStartInfo`, applying `ITestHostEnvironmentVariableProvider`/`ITestHostEnvironmentVariableProvider` validation) - Responsibility: Preparing process start info, environment variables, and validating them via extensions 2. **`TestHostControllersTestHost.ProcessLifecycle.cs`** *(partial class)* - Contents: `LaunchUsingCustomLauncherAsync`, the process-launch/wait-for-exit block (including the cancellation-triggered termination logic), and `OnTestHostProcessStartedAsync`/`OnTestHostProcessExitedAsync` lifetime-handler invocation helpers extracted as private methods - Responsibility: Starting the test host process and coordinating `ITestHostProcessLifetimeHandler` notifications around its lifetime 3. **`TestHostControllersTestHost.Ipc.cs`** *(partial class)* - Contents: `GetAuthorizedSecurityIdentitiesAsync`, `HandleRequestAsync`, and the named-pipe IPC server setup/handshake logic - Responsibility: Managing the controller↔test-host IPC channel and PID handshake 4. **`TestHostControllersTestHost.cs`** *(remaining, trimmed)* - Contents: Class fields, constructor, `IExtension` properties, `DisposeServicesAsync`, `Dispose`, and a slimmed-down `InternalRunAsync` that delegates to the extracted private methods (coverage-threshold/exit-code computation can remain here or move to a small helper method) - Responsibility: Orchestration entry point (`InternalRunAsync`) and disposal ### Implementation Guidelines 1. **Preserve Behavior**: All existing functionality must work identically after the split 2. **Maintain Public API**: Keep exported/public symbols accessible with the same names (this class is `internal`, so no public API changes are expected, but constructor/property signatures must remain unchanged) 3. **Update Imports**: Fix all import paths throughout the codebase (partial-class split does not require external import changes, but `using` directives per file must be adjusted) 4. **Test After Each Split**: Run the test suite after each incremental change (`./build.sh -test`, focusing on `Microsoft.Testing.Platform.UnitTests` and related acceptance tests) 5. **One File at a Time**: Split one module at a time to make review easier — start with `Ipc.cs` (most self-contained), then `ProcessLifecycle.cs`, then `EnvironmentSetup.cs` ### Acceptance Criteria - [ ] Original file is split into focused partial-class files - [ ] Each new file is under 300 lines - [ ] All tests pass after refactoring - [ ] No breaking changes to public API - [ ] All import paths updated correctly --- **Priority**: Medium **Effort**: Medium (single class, but the `InternalRunAsync` method has intricate cancellation/error-handling control flow that must be preserved exactly) **Expected Impact**: Improved code navigability, easier testing, reduced merge conflicts <!-- gh-aw-tracker-id: daily-file-diet --> > 🤖 **Automated content by GitHub Copilot.** Generated by the [Daily File Diet](https://github.com/microsoft/testfx/actions/runs/31210194010/agentic_workflow) workflow. · auto · 35.2 AIC · ⌖ 2.09 AIC · ⊞ 11.4K · [◷]( · [◷](https://github.com/search?q=repo%3Amicrosoft%2Ftestfx+is%3Aissue+%22gh-aw-workflow-call-id%3A+microsoft%2Ftestfx%2Fdaily-file-diet%22&type=issues)) > - [x] expires <!-- gh-aw-expires: 2026-08-09T19:15:35.163Z --> on Aug 9, 2026, 7:15 PM UTC <!-- gh-aw-agentic-workflow: Daily File Diet, gh-aw-tracker-id: daily-file-diet, engine: copilot, model: auto, id: 31210194010, workflow_id: daily-file-diet, run: https://github.com/microsoft/testfx/actions/runs/31210194010 --> <!-- gh-aw-workflow-id: daily-file-diet --> <!-- gh-aw-workflow-call-id: microsoft/testfx/daily-file-diet -->
0 条评论