Overview
The file src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs has grown to 1045 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.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs
- Size: 1045 lines
- Language: C#
Structural Analysis
The file contains two top-level types:
HangDumpProcessLifetimeHandler (internal sealed class, ~990 lines) implementing ITestHostProcessLifetimeHandler, IOutputDeviceDataProducer, IDataProducer, IAsyncDisposable/IDisposable. It mixes several distinct concerns:
- Core lifecycle members: constructor, fields,
IsEnabledAsync, BeforeTestHostProcessStartAsync, CallbackAsync, OnTestHostProcessStartedAsync, OnTestHostProcessExitedAsync, timer/deadline handling (OnDeadlineTimerElapsed, GetTimerDueTime), and Dispose/DisposeAsync.
- Process-tree diagnostics helpers:
GetProcessTreeWithTimeoutAsync, QueryOnceAndDumpTreeAsync, TryGetProcessById, GetInProgressTestsAsync, QueryInProgressTestsWithTimeoutAsync, RunBestEffortDiagnosticAsync, GetDiskInfo.
- Dump-taking logic:
TriggerDumpOnce, TakeDumpOfTreeAsync, TakeDumpAsync, GetDumpFileNames/DumpFileNames, EnsureProcessIdPlaceholder, GetDumpFileNamePattern.
OutputDeviceWriter (internal sealed class, ~20 lines) — an unrelated helper for writing output device data, tacked onto the end of the same file.
Refactoring Strategy
Proposed File Splits
-
HangDumpProcessLifetimeHandler.cs (keep, trimmed to ~350–400 lines)
- Contents: fields, constructor, properties (
Uid, Version, DisplayName, Description, DataTypesProduced), IsEnabledAsync, BeforeTestHostProcessStartAsync, CallbackAsync, OnTestHostProcessStartedAsync, OnTestHostProcessExitedAsync, OnDeadlineTimerElapsed, GetTimerDueTime, Dispose, DisposeAsync
- Responsibility: Core
ITestHostProcessLifetimeHandler lifecycle orchestration and disposal.
-
HangDumpProcessLifetimeHandler.ProcessTree.cs (partial class)
- Contents:
GetProcessTreeWithTimeoutAsync, QueryOnceAndDumpTreeAsync, TryGetProcessById, GetInProgressTestsAsync, QueryInProgressTestsWithTimeoutAsync, RunBestEffortDiagnosticAsync, GetDiskInfo
- Responsibility: Process-tree discovery and best-effort diagnostic querying.
-
HangDumpProcessLifetimeHandler.DumpTaking.cs (partial class)
- Contents:
TriggerDumpOnce, TakeDumpOfTreeAsync, TakeDumpAsync, GetDumpFileNames, DumpFileNames, EnsureProcessIdPlaceholder, GetDumpFileNamePattern, NotifyCrashDumpServiceIfEnabled
- Responsibility: Triggering and producing the actual hang dump artifacts.
-
OutputDeviceWriter.cs
- Contents:
OutputDeviceWriter class
- Responsibility: Thin wrapper for writing
IOutputDeviceData — unrelated to hang-dump logic and should live in its own file.
Implementation Guidelines
- Preserve Behavior: All existing functionality must work identically after the split
- Maintain Public API: Keep exported/public symbols accessible with the same names (mark the class
partial where split across files)
- Update Imports: Fix all import paths/usings throughout the split files
- Test After Each Split: Run the test suite after each incremental change
- One File at a Time: Split one module at a time to make review easier
Acceptance Criteria
Priority: Medium
Effort: Medium — mechanical extraction using partial classes with test verification at each step
Expected Impact: Improved code navigability, easier testing, reduced merge conflicts
🤖 Automated content by GitHub Copilot. Generated by the Daily File Diet workflow. · auto · 25.5 AIC · ⌖ 1.64 AIC · ⊞ 11.4K · [◷]( · ◷)
Overview
The file
src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cshas grown to 1045 lines, making it harder to navigate and maintain. This task involves refactoring it into smaller, more focused files.Current State
src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.csStructural Analysis
The file contains two top-level types:
HangDumpProcessLifetimeHandler(internal sealed class, ~990 lines) implementingITestHostProcessLifetimeHandler,IOutputDeviceDataProducer,IDataProducer,IAsyncDisposable/IDisposable. It mixes several distinct concerns:IsEnabledAsync,BeforeTestHostProcessStartAsync,CallbackAsync,OnTestHostProcessStartedAsync,OnTestHostProcessExitedAsync, timer/deadline handling (OnDeadlineTimerElapsed,GetTimerDueTime), andDispose/DisposeAsync.GetProcessTreeWithTimeoutAsync,QueryOnceAndDumpTreeAsync,TryGetProcessById,GetInProgressTestsAsync,QueryInProgressTestsWithTimeoutAsync,RunBestEffortDiagnosticAsync,GetDiskInfo.TriggerDumpOnce,TakeDumpOfTreeAsync,TakeDumpAsync,GetDumpFileNames/DumpFileNames,EnsureProcessIdPlaceholder,GetDumpFileNamePattern.OutputDeviceWriter(internal sealed class, ~20 lines) — an unrelated helper for writing output device data, tacked onto the end of the same file.Refactoring Strategy
Proposed File Splits
HangDumpProcessLifetimeHandler.cs(keep, trimmed to ~350–400 lines)Uid,Version,DisplayName,Description,DataTypesProduced),IsEnabledAsync,BeforeTestHostProcessStartAsync,CallbackAsync,OnTestHostProcessStartedAsync,OnTestHostProcessExitedAsync,OnDeadlineTimerElapsed,GetTimerDueTime,Dispose,DisposeAsyncITestHostProcessLifetimeHandlerlifecycle orchestration and disposal.HangDumpProcessLifetimeHandler.ProcessTree.cs(partial class)GetProcessTreeWithTimeoutAsync,QueryOnceAndDumpTreeAsync,TryGetProcessById,GetInProgressTestsAsync,QueryInProgressTestsWithTimeoutAsync,RunBestEffortDiagnosticAsync,GetDiskInfoHangDumpProcessLifetimeHandler.DumpTaking.cs(partial class)TriggerDumpOnce,TakeDumpOfTreeAsync,TakeDumpAsync,GetDumpFileNames,DumpFileNames,EnsureProcessIdPlaceholder,GetDumpFileNamePattern,NotifyCrashDumpServiceIfEnabledOutputDeviceWriter.csOutputDeviceWriterclassIOutputDeviceData— unrelated to hang-dump logic and should live in its own file.Implementation Guidelines
partialwhere split across files)Acceptance Criteria
partial classforHangDumpProcessLifetimeHandler)Priority: Medium
Effort: Medium — mechanical extraction using partial classes with test verification at each step
Expected Impact: Improved code navigability, easier testing, reduced merge conflicts