From ce0570850d3e115338373f8d595d53305dfdc817 Mon Sep 17 00:00:00 2001 From: Roger Johansson Date: Sat, 21 Mar 2026 10:43:43 +0100 Subject: [PATCH] Refactor profile input loading into focused components --- .../Input/HeapProfileInputLoader.cs | 79 +++++ .../Input/MemoryProfileResultFactory.cs | 37 +++ .../Input/ProfileInputDefaultsPolicy.cs | 37 +++ src/ProfileTool/Input/ProfileInputKind.cs | 11 + .../Input/ProfileInputKindResolver.cs | 24 ++ .../Input/ProfileInputLabelFactory.cs | 11 + .../Input/TraceProfileInputLoader.cs | 152 +++++++++ src/ProfileTool/ProfileCollectionRunner.cs | 2 +- src/ProfileTool/ProfileInputLoader.cs | 297 ++---------------- .../ProfilerExecutionRequestFactory.cs | 4 +- .../ProfileInputLoaderTests.cs | 6 +- 11 files changed, 376 insertions(+), 284 deletions(-) create mode 100644 src/ProfileTool/Input/HeapProfileInputLoader.cs create mode 100644 src/ProfileTool/Input/MemoryProfileResultFactory.cs create mode 100644 src/ProfileTool/Input/ProfileInputDefaultsPolicy.cs create mode 100644 src/ProfileTool/Input/ProfileInputKind.cs create mode 100644 src/ProfileTool/Input/ProfileInputKindResolver.cs create mode 100644 src/ProfileTool/Input/ProfileInputLabelFactory.cs create mode 100644 src/ProfileTool/Input/TraceProfileInputLoader.cs diff --git a/src/ProfileTool/Input/HeapProfileInputLoader.cs b/src/ProfileTool/Input/HeapProfileInputLoader.cs new file mode 100644 index 0000000..6512232 --- /dev/null +++ b/src/ProfileTool/Input/HeapProfileInputLoader.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Spectre.Console; + +namespace Asynkron.Profiler; + +internal sealed class HeapProfileInputLoader +{ + private readonly Func _getTheme; + private readonly Func _ensureToolAvailable; + private readonly Func, string?, int, (bool Success, string StdOut, string StdErr)> _runProcess; + private readonly Func _parseGcdumpReport; + private readonly Action _writeLine; + private readonly string _dotnetGcdumpInstallHint; + + public HeapProfileInputLoader( + Func getTheme, + Func ensureToolAvailable, + Func, string?, int, (bool Success, string StdOut, string StdErr)> runProcess, + Func parseGcdumpReport, + Action writeLine, + string dotnetGcdumpInstallHint) + { + _getTheme = getTheme; + _ensureToolAvailable = ensureToolAvailable; + _runProcess = runProcess; + _parseGcdumpReport = parseGcdumpReport; + _writeLine = writeLine; + _dotnetGcdumpInstallHint = dotnetGcdumpInstallHint; + } + + public HeapProfileResult? Load(string inputPath) + { + if (!TryEnsureInputExists(inputPath)) + { + return null; + } + + return ProfileInputKindResolver.Resolve(inputPath) switch + { + ProfileInputKind.Gcdump => LoadGcdump(inputPath), + ProfileInputKind.HeapReport => _parseGcdumpReport(File.ReadAllText(inputPath)), + _ => WriteUnsupportedInput(inputPath) + }; + } + + private HeapProfileResult? LoadGcdump(string inputPath) + { + if (!_ensureToolAvailable("dotnet-gcdump", _dotnetGcdumpInstallHint)) + { + return null; + } + + return GcdumpReportLoader.Load( + inputPath, + _getTheme(), + _runProcess, + _parseGcdumpReport, + _writeLine); + } + + private bool TryEnsureInputExists(string inputPath) + { + if (File.Exists(inputPath)) + { + return true; + } + + _writeLine($"[{_getTheme().ErrorColor}]Input file not found:[/] {Markup.Escape(inputPath)}"); + return false; + } + + private HeapProfileResult? WriteUnsupportedInput(string inputPath) + { + _writeLine($"[{_getTheme().ErrorColor}]Unsupported heap input:[/] {Markup.Escape(inputPath)}"); + return null; + } +} diff --git a/src/ProfileTool/Input/MemoryProfileResultFactory.cs b/src/ProfileTool/Input/MemoryProfileResultFactory.cs new file mode 100644 index 0000000..80e2fdd --- /dev/null +++ b/src/ProfileTool/Input/MemoryProfileResultFactory.cs @@ -0,0 +1,37 @@ +using System.Linq; +using static Asynkron.Profiler.CallTreeHelpers; + +namespace Asynkron.Profiler; + +internal static class MemoryProfileResultFactory +{ + public static MemoryProfileResult Create(AllocationCallTreeResult callTree) + { + var allocationEntries = callTree.TypeRoots + .OrderByDescending(root => root.TotalBytes) + .Take(50) + .Select(root => new AllocationEntry(root.Name, root.Count, FormatBytes(root.TotalBytes))) + .ToList(); + + var totalAllocated = FormatBytes(callTree.TotalBytes); + + return new MemoryProfileResult( + null, + null, + null, + totalAllocated, + null, + null, + null, + null, + null, + null, + null, + null, + totalAllocated, + allocationEntries, + callTree, + null, + null); + } +} diff --git a/src/ProfileTool/Input/ProfileInputDefaultsPolicy.cs b/src/ProfileTool/Input/ProfileInputDefaultsPolicy.cs new file mode 100644 index 0000000..f8ced6e --- /dev/null +++ b/src/ProfileTool/Input/ProfileInputDefaultsPolicy.cs @@ -0,0 +1,37 @@ +namespace Asynkron.Profiler; + +internal static class ProfileInputDefaultsPolicy +{ + public static void Apply( + string inputPath, + ref bool runCpu, + ref bool runMemory, + ref bool runHeap, + ref bool runException, + ref bool runContention) + { + switch (ProfileInputKindResolver.Resolve(inputPath)) + { + case ProfileInputKind.Speedscope: + runCpu = true; + break; + case ProfileInputKind.NetTrace: + runCpu = true; + runException = true; + runContention = true; + break; + case ProfileInputKind.Etlx: + runMemory = true; + runException = true; + runContention = true; + break; + case ProfileInputKind.Gcdump: + case ProfileInputKind.HeapReport: + runHeap = true; + break; + default: + runCpu = true; + break; + } + } +} diff --git a/src/ProfileTool/Input/ProfileInputKind.cs b/src/ProfileTool/Input/ProfileInputKind.cs new file mode 100644 index 0000000..6c7ff98 --- /dev/null +++ b/src/ProfileTool/Input/ProfileInputKind.cs @@ -0,0 +1,11 @@ +namespace Asynkron.Profiler; + +internal enum ProfileInputKind +{ + Unknown, + Speedscope, + NetTrace, + Etlx, + Gcdump, + HeapReport +} diff --git a/src/ProfileTool/Input/ProfileInputKindResolver.cs b/src/ProfileTool/Input/ProfileInputKindResolver.cs new file mode 100644 index 0000000..cf93864 --- /dev/null +++ b/src/ProfileTool/Input/ProfileInputKindResolver.cs @@ -0,0 +1,24 @@ +using System.IO; + +namespace Asynkron.Profiler; + +internal static class ProfileInputKindResolver +{ + public static ProfileInputKind Resolve(string inputPath) + { + return Path.GetExtension(inputPath).ToLowerInvariant() switch + { + ".json" => ProfileInputKind.Speedscope, + ".nettrace" => ProfileInputKind.NetTrace, + ".etlx" => ProfileInputKind.Etlx, + ".gcdump" => ProfileInputKind.Gcdump, + ".txt" or ".log" => ProfileInputKind.HeapReport, + _ => ProfileInputKind.Unknown + }; + } + + public static bool IsTrace(ProfileInputKind kind) + { + return kind is ProfileInputKind.NetTrace or ProfileInputKind.Etlx; + } +} diff --git a/src/ProfileTool/Input/ProfileInputLabelFactory.cs b/src/ProfileTool/Input/ProfileInputLabelFactory.cs new file mode 100644 index 0000000..8df07ca --- /dev/null +++ b/src/ProfileTool/Input/ProfileInputLabelFactory.cs @@ -0,0 +1,11 @@ +using System.IO; + +namespace Asynkron.Profiler; + +internal static class ProfileInputLabelFactory +{ + public static string Build(string inputPath) + { + return FileLabelSanitizer.Sanitize(Path.GetFileNameWithoutExtension(inputPath), "input"); + } +} diff --git a/src/ProfileTool/Input/TraceProfileInputLoader.cs b/src/ProfileTool/Input/TraceProfileInputLoader.cs new file mode 100644 index 0000000..5412ce4 --- /dev/null +++ b/src/ProfileTool/Input/TraceProfileInputLoader.cs @@ -0,0 +1,152 @@ +using System; +using System.IO; +using Spectre.Console; + +namespace Asynkron.Profiler; + +internal sealed class TraceProfileInputLoader +{ + private readonly ProfilerTraceAnalyzer _traceAnalyzer; + private readonly Func _getTheme; + private readonly Action _writeLine; + + public TraceProfileInputLoader( + ProfilerTraceAnalyzer traceAnalyzer, + Func getTheme, + Action writeLine) + { + _traceAnalyzer = traceAnalyzer; + _getTheme = getTheme; + _writeLine = writeLine; + } + + public CpuProfileResult? LoadCpu(string inputPath) + { + if (!TryEnsureInputExists(inputPath)) + { + return null; + } + + return ProfileInputKindResolver.Resolve(inputPath) switch + { + ProfileInputKind.Speedscope => AnalyzeSpeedscope(inputPath), + var kind when ProfileInputKindResolver.IsTrace(kind) => AnalyzeCpuTrace(inputPath), + _ => WriteUnsupportedInput("Unsupported CPU input", inputPath) + }; + } + + public MemoryProfileResult? LoadMemory(string inputPath) + { + var callTree = LoadTraceInput(inputPath, "Unsupported memory input", AnalyzeAllocationTrace); + return callTree == null ? null : MemoryProfileResultFactory.Create(callTree); + } + + public ExceptionProfileResult? LoadException(string inputPath) + { + return LoadTraceInput(inputPath, "Unsupported exception input", AnalyzeExceptionTrace); + } + + public ContentionProfileResult? LoadContention(string inputPath) + { + return LoadTraceInput(inputPath, "Unsupported contention input", AnalyzeContentionTrace); + } + + public CpuProfileResult? AnalyzeCpuTrace(string traceFile) + { + var result = RunAnalysis(() => _traceAnalyzer.AnalyzeCpuTrace(traceFile), "CPU trace parse failed"); + if (result == null) + { + return null; + } + + if (result.AllFunctions.Count == 0) + { + _writeLine($"[{_getTheme().AccentColor}]No CPU samples found in trace.[/]"); + return null; + } + + return result; + } + + public AllocationCallTreeResult? AnalyzeAllocationTrace(string traceFile) + { + return RunAnalysis(() => _traceAnalyzer.AnalyzeAllocationTrace(traceFile), "Allocation trace parse failed"); + } + + public ExceptionProfileResult? AnalyzeExceptionTrace(string traceFile) + { + return RunAnalysis(() => _traceAnalyzer.AnalyzeExceptionTrace(traceFile), "Exception trace parse failed"); + } + + public ContentionProfileResult? AnalyzeContentionTrace(string traceFile) + { + return RunAnalysis(() => _traceAnalyzer.AnalyzeContentionTrace(traceFile), "Contention trace parse failed"); + } + + private CpuProfileResult? AnalyzeSpeedscope(string speedscopePath) + { + return RunAnalysis(() => ProfilerTraceAnalyzer.AnalyzeSpeedscope(speedscopePath), "Speedscope parse failed"); + } + + private TResult? LoadTraceInput( + string inputPath, + string unsupportedMessage, + Func analyzeTrace) + where TResult : class + { + if (!TryValidateTraceInput(inputPath, unsupportedMessage)) + { + return null; + } + + return analyzeTrace(inputPath); + } + + private TResult? RunAnalysis(Func analyze, string failureLabel) + where TResult : class + { + try + { + return analyze(); + } + catch (Exception ex) + { + _writeLine($"[{_getTheme().AccentColor}]{failureLabel}:[/] {Markup.Escape(ex.Message)}"); + return null; + } + } + + private bool TryValidateTraceInput(string inputPath, string unsupportedMessage) + { + if (!TryEnsureInputExists(inputPath)) + { + return false; + } + + if (ProfileInputKindResolver.IsTrace(ProfileInputKindResolver.Resolve(inputPath))) + { + return true; + } + + WriteUnsupportedInput(unsupportedMessage, inputPath); + return false; + } + + private bool TryEnsureInputExists(string inputPath) + { + if (File.Exists(inputPath)) + { + return true; + } + + _writeLine($"[{_getTheme().ErrorColor}]Input file not found:[/] {Markup.Escape(inputPath)}"); + return false; + } + + private TResult? WriteUnsupportedInput(string message, string inputPath) + where TResult : class + { + _writeLine($"[{_getTheme().ErrorColor}]{message}:[/] {Markup.Escape(inputPath)}"); + return null; + } +} diff --git a/src/ProfileTool/ProfileCollectionRunner.cs b/src/ProfileTool/ProfileCollectionRunner.cs index d27a63b..09e724a 100644 --- a/src/ProfileTool/ProfileCollectionRunner.cs +++ b/src/ProfileTool/ProfileCollectionRunner.cs @@ -92,7 +92,7 @@ public ProfileCollectionRunner( }, _profileInputLoader.AnalyzeAllocationTrace); - return callTree == null ? null : ProfileInputLoader.BuildMemoryProfileResult(callTree); + return callTree == null ? null : MemoryProfileResultFactory.Create(callTree); } public ExceptionProfileResult? RunExceptionProfile(string[] command, string label) diff --git a/src/ProfileTool/ProfileInputLoader.cs b/src/ProfileTool/ProfileInputLoader.cs index 52d0a9b..92e667f 100644 --- a/src/ProfileTool/ProfileInputLoader.cs +++ b/src/ProfileTool/ProfileInputLoader.cs @@ -1,22 +1,12 @@ using System; using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using Spectre.Console; -using static Asynkron.Profiler.CallTreeHelpers; namespace Asynkron.Profiler; internal sealed class ProfileInputLoader { - private readonly ProfilerTraceAnalyzer _traceAnalyzer; - private readonly Func _getTheme; - private readonly Func _ensureToolAvailable; - private readonly Func, string?, int, (bool Success, string StdOut, string StdErr)> _runProcess; - private readonly Func _parseGcdumpReport; - private readonly Action _writeLine; - private readonly string _dotnetGcdumpInstallHint; + private readonly TraceProfileInputLoader _traceInputLoader; + private readonly HeapProfileInputLoader _heapInputLoader; public ProfileInputLoader( ProfilerTraceAnalyzer traceAnalyzer, @@ -27,280 +17,31 @@ public ProfileInputLoader( Action writeLine, string dotnetGcdumpInstallHint) { - _traceAnalyzer = traceAnalyzer; - _getTheme = getTheme; - _ensureToolAvailable = ensureToolAvailable; - _runProcess = runProcess; - _parseGcdumpReport = parseGcdumpReport; - _writeLine = writeLine; - _dotnetGcdumpInstallHint = dotnetGcdumpInstallHint; + _traceInputLoader = new TraceProfileInputLoader(traceAnalyzer, getTheme, writeLine); + _heapInputLoader = new HeapProfileInputLoader( + getTheme, + ensureToolAvailable, + runProcess, + parseGcdumpReport, + writeLine, + dotnetGcdumpInstallHint); } - public CpuProfileResult? LoadCpu(string inputPath) - { - if (!TryEnsureInputExists(inputPath)) - { - return null; - } - - var extension = GetNormalizedExtension(inputPath); - if (extension == ".json") - { - return AnalyzeSpeedscope(inputPath); - } - - if (!IsSupportedExtension(extension, ".nettrace", ".etlx")) - { - WriteUnsupportedInput("Unsupported CPU input", inputPath); - return null; - } - - return AnalyzeCpuTrace(inputPath); - } - - public MemoryProfileResult? LoadMemory(string inputPath) - { - if (!TryValidateTraceInput(inputPath, "Unsupported memory input")) - { - return null; - } - - var callTree = AnalyzeAllocationTrace(inputPath); - return callTree == null ? null : BuildMemoryProfileResult(callTree); - } - - public ExceptionProfileResult? LoadException(string inputPath) - { - if (!TryValidateTraceInput(inputPath, "Unsupported exception input")) - { - return null; - } + public CpuProfileResult? LoadCpu(string inputPath) => _traceInputLoader.LoadCpu(inputPath); - return AnalyzeExceptionTrace(inputPath); - } + public MemoryProfileResult? LoadMemory(string inputPath) => _traceInputLoader.LoadMemory(inputPath); - public ContentionProfileResult? LoadContention(string inputPath) - { - if (!TryValidateTraceInput(inputPath, "Unsupported contention input")) - { - return null; - } + public ExceptionProfileResult? LoadException(string inputPath) => _traceInputLoader.LoadException(inputPath); - return AnalyzeContentionTrace(inputPath); - } + public ContentionProfileResult? LoadContention(string inputPath) => _traceInputLoader.LoadContention(inputPath); - public HeapProfileResult? LoadHeap(string inputPath) - { - if (!TryEnsureInputExists(inputPath)) - { - return null; - } + public HeapProfileResult? LoadHeap(string inputPath) => _heapInputLoader.Load(inputPath); - var extension = GetNormalizedExtension(inputPath); - if (extension == ".gcdump") - { - if (!_ensureToolAvailable("dotnet-gcdump", _dotnetGcdumpInstallHint)) - { - return null; - } + public CpuProfileResult? AnalyzeCpuTrace(string traceFile) => _traceInputLoader.AnalyzeCpuTrace(traceFile); - return GcdumpReportLoader.Load( - inputPath, - _getTheme(), - _runProcess, - _parseGcdumpReport, - _writeLine); - } + public AllocationCallTreeResult? AnalyzeAllocationTrace(string traceFile) => _traceInputLoader.AnalyzeAllocationTrace(traceFile); - if (extension is ".txt" or ".log") - { - return _parseGcdumpReport(File.ReadAllText(inputPath)); - } + public ExceptionProfileResult? AnalyzeExceptionTrace(string traceFile) => _traceInputLoader.AnalyzeExceptionTrace(traceFile); - WriteUnsupportedInput("Unsupported heap input", inputPath); - return null; - } - - public CpuProfileResult? AnalyzeCpuTrace(string traceFile) - { - try - { - var result = _traceAnalyzer.AnalyzeCpuTrace(traceFile); - if (result.AllFunctions.Count == 0) - { - _writeLine($"[{_getTheme().AccentColor}]No CPU samples found in trace.[/]"); - return null; - } - - return result; - } - catch (Exception ex) - { - _writeLine($"[{_getTheme().AccentColor}]CPU trace parse failed:[/] {Markup.Escape(ex.Message)}"); - return null; - } - } - - public AllocationCallTreeResult? AnalyzeAllocationTrace(string traceFile) - { - try - { - return _traceAnalyzer.AnalyzeAllocationTrace(traceFile); - } - catch (Exception ex) - { - _writeLine($"[{_getTheme().AccentColor}]Allocation trace parse failed:[/] {Markup.Escape(ex.Message)}"); - return null; - } - } - - public ExceptionProfileResult? AnalyzeExceptionTrace(string traceFile) - { - try - { - return _traceAnalyzer.AnalyzeExceptionTrace(traceFile); - } - catch (Exception ex) - { - _writeLine($"[{_getTheme().AccentColor}]Exception trace parse failed:[/] {Markup.Escape(ex.Message)}"); - return null; - } - } - - public ContentionProfileResult? AnalyzeContentionTrace(string traceFile) - { - try - { - return _traceAnalyzer.AnalyzeContentionTrace(traceFile); - } - catch (Exception ex) - { - _writeLine($"[{_getTheme().AccentColor}]Contention trace parse failed:[/] {Markup.Escape(ex.Message)}"); - return null; - } - } - - public static MemoryProfileResult BuildMemoryProfileResult(AllocationCallTreeResult callTree) - { - var allocationEntries = callTree.TypeRoots - .OrderByDescending(root => root.TotalBytes) - .Take(50) - .Select(root => new AllocationEntry(root.Name, root.Count, FormatBytes(root.TotalBytes))) - .ToList(); - - var totalAllocated = FormatBytes(callTree.TotalBytes); - - return new MemoryProfileResult( - null, - null, - null, - totalAllocated, - null, - null, - null, - null, - null, - null, - null, - null, - totalAllocated, - allocationEntries, - callTree, - null, - null); - } - - public static string BuildInputLabel(string inputPath) - { - return FileLabelSanitizer.Sanitize(Path.GetFileNameWithoutExtension(inputPath), "input"); - } - - public static void ApplyInputDefaults( - string inputPath, - ref bool runCpu, - ref bool runMemory, - ref bool runHeap, - ref bool runException, - ref bool runContention) - { - switch (GetNormalizedExtension(inputPath)) - { - case ".json": - runCpu = true; - break; - case ".nettrace": - runCpu = true; - runException = true; - runContention = true; - break; - case ".etlx": - runMemory = true; - runException = true; - runContention = true; - break; - case ".gcdump": - case ".txt": - case ".log": - runHeap = true; - break; - default: - runCpu = true; - break; - } - } - - private CpuProfileResult? AnalyzeSpeedscope(string speedscopePath) - { - try - { - return ProfilerTraceAnalyzer.AnalyzeSpeedscope(speedscopePath); - } - catch (Exception ex) - { - _writeLine($"[{_getTheme().AccentColor}]Speedscope parse failed:[/] {Markup.Escape(ex.Message)}"); - return null; - } - } - - private bool TryValidateTraceInput(string inputPath, string unsupportedMessage) - { - if (!TryEnsureInputExists(inputPath)) - { - return false; - } - - if (IsSupportedExtension(GetNormalizedExtension(inputPath), ".nettrace", ".etlx")) - { - return true; - } - - WriteUnsupportedInput(unsupportedMessage, inputPath); - return false; - } - - private bool TryEnsureInputExists(string inputPath) - { - if (File.Exists(inputPath)) - { - return true; - } - - _writeLine($"[{_getTheme().ErrorColor}]Input file not found:[/] {Markup.Escape(inputPath)}"); - return false; - } - - private void WriteUnsupportedInput(string message, string inputPath) - { - _writeLine($"[{_getTheme().ErrorColor}]{message}:[/] {Markup.Escape(inputPath)}"); - } - - private static string GetNormalizedExtension(string inputPath) - { - return Path.GetExtension(inputPath).ToLowerInvariant(); - } - - private static bool IsSupportedExtension(string extension, params string[] allowedExtensions) - { - return allowedExtensions.Contains(extension, StringComparer.Ordinal); - } + public ContentionProfileResult? AnalyzeContentionTrace(string traceFile) => _traceInputLoader.AnalyzeContentionTrace(traceFile); } diff --git a/src/ProfileTool/ProfilerExecutionRequestFactory.cs b/src/ProfileTool/ProfilerExecutionRequestFactory.cs index fdb51aa..60c9fbe 100644 --- a/src/ProfileTool/ProfilerExecutionRequestFactory.cs +++ b/src/ProfileTool/ProfilerExecutionRequestFactory.cs @@ -37,13 +37,13 @@ public ProfilerExecutionRequestFactory( if (hasInput) { - label = ProfileInputLoader.BuildInputLabel(invocation.InputPath!); + label = ProfileInputLabelFactory.Build(invocation.InputPath!); description = invocation.InputPath!; command = Array.Empty(); if (!hasExplicitModes) { - ProfileInputLoader.ApplyInputDefaults( + ProfileInputDefaultsPolicy.Apply( invocation.InputPath!, ref runCpu, ref runMemory, diff --git a/tests/Asynkron.Profiler.Tests/ProfileInputLoaderTests.cs b/tests/Asynkron.Profiler.Tests/ProfileInputLoaderTests.cs index a3b3b2d..fb243da 100644 --- a/tests/Asynkron.Profiler.Tests/ProfileInputLoaderTests.cs +++ b/tests/Asynkron.Profiler.Tests/ProfileInputLoaderTests.cs @@ -31,7 +31,7 @@ public void BuildMemoryProfileResult_SortsEntriesAndCapsAtFifty() .ToArray(); var callTree = new AllocationCallTreeResult(roots.Sum(root => root.TotalBytes), roots.Sum(root => root.Count), roots); - var result = ProfileInputLoader.BuildMemoryProfileResult(callTree); + var result = MemoryProfileResultFactory.Create(callTree); Assert.Equal("1.50 KB", result.TotalAllocated); Assert.Equal("1.50 KB", result.AllocationTotal); @@ -103,7 +103,7 @@ public void LoadHeap_RejectsUnsupportedInputs() [Fact] public void BuildInputLabel_FallsBackToInputWhenFileNameIsMissing() { - var label = ProfileInputLoader.BuildInputLabel(string.Empty); + var label = ProfileInputLabelFactory.Build(string.Empty); Assert.Equal("input", label); } @@ -122,7 +122,7 @@ private static void AssertModes( var runException = false; var runContention = false; - ProfileInputLoader.ApplyInputDefaults( + ProfileInputDefaultsPolicy.Apply( inputPath, ref runCpu, ref runMemory,