Skip to content

Abstract VSTest message logging in PlatformServices (Phase 1 of platform-agnostic effort)#9548

Open
Evangelink wants to merge 1 commit into
mainfrom
dev/amauryleve/abstract-vstest-types-platformservices
Open

Abstract VSTest message logging in PlatformServices (Phase 1 of platform-agnostic effort)#9548
Evangelink wants to merge 1 commit into
mainfrom
dev/amauryleve/abstract-vstest-types-platformservices

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Why

This is the first, self-contained slice of a larger effort to make MSTestAdapter.PlatformServices platform-agnostic by removing its dependency on the VSTest object model (Microsoft.TestPlatform.ObjectModel). The end goal is for the VSTest coupling to live only in the adapter layer (MSTest.TestAdapter), so the platform-services engine can eventually be driven by an MTP-native adapter without round-tripping through the VSTest bridge.

The full phased plan (0–8) is tracked separately; this PR delivers Phase 0 + Phase 1 (message logging) only, to keep the change reviewable.

What

Introduces a platform-agnostic message-logging abstraction and migrates the standalone logger role in PlatformServices off VSTest types. The VSTest connection is now made at the adapter boundary.

  • New neutral abstraction (functional, non-VSTest naming):
    • IAdapterMessageLoggerSendMessage(MessageLevel, string), reusing the existing neutral MessageLevel enum from TestFramework.Extensions.
    • AdapterMessageLoggerExtensions.ToAdapterMessageLogger(this IMessageLogger) — the single VSTest → neutral bridge (internal HostMessageLogger, maps via the pre-existing ToTestMessageLevel()).
  • Migrated to the neutral logger (IMessageLogger/TestMessageLevelIAdapterMessageLogger/MessageLevel): MSTestDiscovererHelpers, MSTestSettings.Configuration, MSTestSettings.RunSettingsXml, UnitTestDiscoverer, TestMethodFilter.
  • Adapter boundary wraps via frameworkHandle.ToAdapterMessageLogger() in MSTestDiscoverer / MSTestExecutor, plus the two execution sites that reuse the framework handle as a logger.

Deliberately out of scope

The recorder's dual logger role (IFrameworkHandle / ITestExecutionRecorder.SendMessage) is intentionally left for the later recorder phase, since there the logger and the recorder are the same object. The ToAdapterMessageLogger bridge stays in PlatformServices as a temporary translation point until that phase.

No behavior change

This is a pure refactor. The MessageLevelTestMessageLevel mapping is 1:1, and no message levels or paths were dropped. Tests keep their Mock<IMessageLogger> and wrap with .ToAdapterMessageLogger() at migrated call sites, so the existing Verify(... TestMessageLevel ...) assertions still exercise the mapping end-to-end.

Verification

  • Full Debug src build green across all TFMs (net462, net8.0, net9.0, UWP, WinUI).
  • MSTestAdapter.PlatformServices.UnitTests: 889 passed.
  • MSTestAdapter.UnitTests: 21 passed.
  • Reviewed with the expert MSTest reviewer agent (two passes); all findings addressed.

Introduce a platform-agnostic IAdapterMessageLogger abstraction (reusing the
existing MessageLevel enum) so the platform services layer no longer depends on
the VSTest IMessageLogger/TestMessageLevel for the standalone message-logger
role. The VSTest bridge (ToAdapterMessageLogger) lives in the adapter-facing
extension and is applied at the MSTestDiscoverer/MSTestExecutor boundary and at
the two execution sites that reuse the framework handle as a logger.

The recorder's dual logger role (IFrameworkHandle/ITestExecutionRecorder) is
intentionally left for the later recorder phase, since logger and recorder are
the same object there.

Tests keep their Mock<IMessageLogger> and wrap with .ToAdapterMessageLogger() at
migrated call sites, so TestMessageLevel Verify assertions are unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 15:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is Phase 1 of the effort to make MSTestAdapter.PlatformServices platform-agnostic by abstracting adapter-to-host message logging away from VSTest’s object model and shifting the translation to the adapter boundary.

Changes:

  • Introduces a neutral message-logging contract (IAdapterMessageLogger) based on the existing MessageLevel enum.
  • Adds a single VSTest→neutral bridge (ToAdapterMessageLogger(this IMessageLogger)) and migrates PlatformServices call sites from IMessageLogger/TestMessageLevel to IAdapterMessageLogger/MessageLevel.
  • Updates adapter and test call sites to wrap existing IMessageLogger mocks/handles with .ToAdapterMessageLogger().
Show a summary per file
File Description
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/RunConfigurationSettingsTests.cs Updates settings population tests to pass the new adapter logger wrapper.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/ObjectModel/UnitTestResultTests.cs Wraps logger when retrieving settings to keep outcome mapping tests exercising the bridge.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestSettingsTests.cs Migrates settings/config tests to the new logger abstraction while retaining TestMessageLevel verifications.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Helpers/UnitTestOutcomeHelperTests.cs Updates settings initialization to use .ToAdapterMessageLogger().
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Execution/UnitTestRunnerTests.cs Wraps logger in runner-related settings reads.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Execution/TypeCacheTests.cs Updates settings read/population paths to use the adapter logger wrapper.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Execution/TestMethodFilterTests.cs Passes an IAdapterMessageLogger into filter expression paths via wrapper.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Execution/TestExecutionManagerTests.cs Updates settings population during execution tests to use the adapter logger wrapper.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Discovery/UnitTestDiscovererTests.cs Migrates discovery tests and test doubles to IAdapterMessageLogger.
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Discovery/TypeEnumeratorTests.cs Updates discovery settings initialization to use .ToAdapterMessageLogger().
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Discovery/AssemblyEnumeratorTests.cs Wraps logger when constructing settings for discovery enumerator tests.
test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs Updates integration discovery helper to pass the adapter logger wrapper.
src/Adapter/MSTestAdapter.PlatformServices/TestMethodFilter.cs Switches filter logging from IMessageLogger/TestMessageLevel to IAdapterMessageLogger/MessageLevel.
src/Adapter/MSTestAdapter.PlatformServices/Services/AdapterMessageLoggerExtensions.cs Adds the VSTest IMessageLoggerIAdapterMessageLogger bridge.
src/Adapter/MSTestAdapter.PlatformServices/MSTestSettings.RunSettingsXml.cs Migrates runsettings parsing logging to IAdapterMessageLogger/MessageLevel.
src/Adapter/MSTestAdapter.PlatformServices/MSTestSettings.Configuration.cs Migrates configuration/runsettings warning logging to IAdapterMessageLogger/MessageLevel.
src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterMessageLogger.cs Introduces the platform-agnostic adapter message logger contract.
src/Adapter/MSTestAdapter.PlatformServices/Helpers/MSTestDiscovererHelpers.cs Updates discovery initialization logging to use the neutral logger.
src/Adapter/MSTestAdapter.PlatformServices/Execution/TestExecutionManager.Parallelization.cs Updates filter-expression acquisition to pass an adapter logger wrapper.
src/Adapter/MSTestAdapter.PlatformServices/Execution/TestExecutionManager.cs Caches an IAdapterMessageLogger wrapper for framework-handle logging during discovery in execution.
src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs Wraps frameworkHandle at the adapter boundary before calling into PlatformServices.
src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs Wraps the VSTest logger once and threads the neutral logger through discovery.

Review details

  • Files reviewed: 23/23 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment on lines +26 to +27
public static IAdapterMessageLogger ToAdapterMessageLogger(this IMessageLogger messageLogger)
=> new HostMessageLogger(messageLogger);
Comment on lines 74 to 76
// Default test set is filtered tests based on user provided filter criteria
ITestCaseFilterExpression? filterExpression = _testMethodFilter.GetFilterExpression(runContext, frameworkHandle, out bool filterHasError);
ITestCaseFilterExpression? filterExpression = _testMethodFilter.GetFilterExpression(runContext, frameworkHandle.ToAdapterMessageLogger(), out bool filterHasError);
if (filterHasError)
""";

var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object);
var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object.ToAdapterMessageLogger());
});

var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object);
var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object.ToAdapterMessageLogger());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants