Skip to content

Fix InvalidOperationException in BuildServerTestHostAsync when telemetry is enabled#8553

Merged
Evangelink merged 5 commits into
mainfrom
dev/amauryleve/fix-server-telemetry-init
May 25, 2026
Merged

Fix InvalidOperationException in BuildServerTestHostAsync when telemetry is enabled#8553
Evangelink merged 5 commits into
mainfrom
dev/amauryleve/fix-server-telemetry-init

Conversation

@Evangelink
Copy link
Copy Markdown
Member

@Evangelink Evangelink commented May 25, 2026

Regression

PR #8211 registered ServerTelemetry in the service provider before calling LogTestHostCreatedAsync inside BuildServerTestHostAsync. Because ServerTestHost's JSON-RPC message handler (_messageHandler) is only initialized inside InternalRunAsync, the build-time TestHostBuilt telemetry event attempted to flow through the not-yet-initialized server, causing ServerTestHost.AssertInitialized to throw InvalidOperationException during TestApplicationBuilder.BuildAsync().

Reported during dogfood of MTP in the Coverage repo:

   at Microsoft.Testing.Platform.Hosts.ServerTestHost.AssertInitialized()
   at Microsoft.Testing.Platform.Hosts.ServerTestHost.SendMessageAsync(...)
   at Microsoft.Testing.Platform.Hosts.ServerTestHost.SendTelemetryEventUpdateAsync(...)
   at Microsoft.Testing.Platform.Telemetry.ServerTelemetry.PushTelemetryToServerTestHostAsync(...)
   at Microsoft.Testing.Platform.Telemetry.ServerTelemetry.LogEventAsync(...)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.LogTestHostCreatedAsync(...)
   at Microsoft.Testing.Platform.Hosts.TestHostBuilder.BuildServerTestHostAsync(...)

The bug does not reproduce in CI because Arcade sets DOTNET_CLI_TELEMETRY_OPTOUT=1 on the test process, which causes LogTestHostCreatedAsync to early-return before reaching ServerTelemetry.

Fix

Move the ReplaceService<ITelemetryCollector>(ServerTelemetry) call below LogTestHostCreatedAsync. The build-time TestHostBuilt event now goes through the originally-registered collector (typically NopTelemetryService), restoring the pre-#8211 behavior for that single event. Runtime telemetry events still flow through ServerTelemetry once the server is fully built and running.

Regression test

Added ServerLoggingTests.RunningInServerJsonRpcModeWithTelemetryEnabled_DoesNotCrashDuringBuildAsync which explicitly opts into telemetry (sets DOTNET_CLI_TELEMETRY_OPTOUT=0 and TESTINGPLATFORM_TELEMETRY_OPTOUT=0 to override any inherited opt-out) and verifies the server boots and responds to Initialize. Without the fix, this test fails with the exact stack trace above; with the fix, it passes.

Also extended ServerModeTestsBase.StartAsServerAndConnectToTheClientAsync with an overload accepting additional environment variables.

Validation

  • Reproduced the original crash with the new test against baseline main.
  • Test passes after the fix.
  • All 901+ Microsoft.Testing.Platform.UnitTests tests pass across net462/net8.0/net9.0.
  • All 3 ServerLoggingTests pass.

…try is enabled

PR #8211 registered ServerTelemetry in the service provider before calling LogTestHostCreatedAsync. Because ServerTestHost's JSON-RPC message handler is only initialized inside InternalRunAsync, the build-time TestHostBuilt telemetry event attempted to flow through the not-yet-initialized server, causing ServerTestHost.AssertInitialized to throw InvalidOperationException during TestApplicationBuilder.BuildAsync().

This change moves the ReplaceService<ITelemetryCollector>(ServerTelemetry) call below LogTestHostCreatedAsync. The build-time TestHostBuilt event now goes through the originally-registered collector (NopTelemetryService), restoring previous behavior. Runtime telemetry events still flow through ServerTelemetry once the server is fully built and running.

Adds a regression integration test that explicitly opts into telemetry (overriding any DOTNET_CLI_TELEMETRY_OPTOUT inherited from Arcade) and verifies the server starts without crashing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 25, 2026 10:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a regression in Microsoft.Testing.Platform server-mode host construction where enabling telemetry could crash during TestApplicationBuilder.BuildAsync() by ensuring the build-time TestHostBuilt telemetry event is sent before ServerTelemetry is registered (i.e., before the JSON-RPC message handler is initialized).

Changes:

  • Reorders ServerTelemetry registration in BuildServerTestHostAsync to occur after LogTestHostCreatedAsync, preventing ServerTestHost.AssertInitialized failures during build.
  • Adds an acceptance regression test that explicitly opts into telemetry and validates the server responds to Initialize.
  • Extends server-mode test infrastructure to allow passing additional environment variables to the spawned server process.
Show a summary per file
File Description
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs Adds an overload to inject additional environment variables into the server-mode test process.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs Adds a regression test to ensure telemetry-enabled server JSON-RPC mode doesn’t crash during build.
src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.Modes.cs Moves ServerTelemetry registration to after the build-time telemetry event is logged to avoid uninitialized JSON-RPC usage.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

…xer assignment

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink
Copy link
Copy Markdown
Member Author

🔍 Build Failure Analysis

Summary — The build failed with CS0103: The name 'EnvironmentVariableConstants' does not exist in the current context because two test files are missing the required using Microsoft.Testing.Platform.Helpers; directive.

Root cause: Missing using directive for EnvironmentVariableConstants

The PR's second commit (6297443) updated ServerModeTestsBase.cs and ServerLoggingTests.cs to reference EnvironmentVariableConstants instead of hard-coded string literals. However, both files are missing the using Microsoft.Testing.Platform.Helpers; directive needed to access this internal class.

EnvironmentVariableConstants is an [Embedded] internal class defined in the Platform assembly, so each consuming assembly needs to explicitly import the Microsoft.Testing.Platform.Helpers namespace.

Affected files / errors

Proposed fix

Add using Microsoft.Testing.Platform.Helpers; to the using directives section of both files. This is consistent with other test files in the same project (e.g., DiagnosticTests.cs, IgnoreExitCodeTests.cs) that already reference EnvironmentVariableConstants.


Build overview
  • Build command: ./build.sh --binaryLog
  • Exit code: 1 (failure)
  • Target framework: net11.0
  • Failed project: MSTest.Acceptance.IntegrationTests.csproj
  • Build time: 00:03:52.88
All MSBuild errors (1)
Code Project File:Line Message
CS0103 MSTest.Acceptance.IntegrationTests ServerMode/ServerModeTestsBase.cs:44 The name 'EnvironmentVariableConstants' does not exist in the current context

Note: The error was reported twice by MSBuild (once for each project that references ServerModeTestsBase.cs), but it's the same root cause.


🤖 Generated by the Build Failure Analysis workflow · commit 6297443

Generated by Build Failure Analysis for issue #8553 · ● 862.5K ·

Copy link
Copy Markdown
Member Author

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

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

Generated by Build Failure Analysis for issue #8553 · ● 862.5K

Comments that could not be inline-anchored

test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs:4

🔧 CS0103 — Add missing using directive for EnvironmentVariableConstants

The new test method RunningInServerJsonRpcModeWithTelemetryEnabled_DoesNotCrashDuringBuildAsync references EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT and EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT but the file is missing the required namespace import.

using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V…

</details>

<details><summary>test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs:7</summary>

🔧 **CS0103** — Add missing using directive for `EnvironmentVariableConstants`

This file now references `EnvironmentVariableConstants.TESTINGPLATFORM_EXIT_PROCESS_ON_UNHANDLED_EXCEPTION` on line 44 but is missing the required namespace import.

```suggestion
using Microsoft.Testing.Platform.Acceptance.IntegrationTests;
using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100;

…dd using

ServerModeTestsBase.cs (shared with MSTest.Acceptance.IntegrationTests via Compile Include) now references EnvironmentVariableConstants. That project did not embed EnvironmentVariableConstants.cs nor declare a global using for Microsoft.Testing.Platform.Helpers, so the build failed with CS0103 under net11.0. Add the Compile Include and an explicit using directive to the shared file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 25, 2026 11:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 1

Comment thread src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.Modes.cs Outdated
Evangelink and others added 2 commits May 25, 2026 15:53
The original comments implied NopTelemetryService was always the collector
active at LogTestHostCreatedAsync, but when telemetry is opted in,
TelemetryManager.BuildTelemetryAsync registers a real collector via the
user-supplied _telemetryFactory. Reword both the pre- and
post-LogTestHostCreatedAsync comments to refer to `the collector previously
registered by TelemetryManager in SetupCommonServicesAsync` so the rationale
stays accurate in both enabled and disabled telemetry scenarios.

Addresses Copilot review feedback on #8553.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 25, 2026 13:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 1

@Evangelink Evangelink merged commit 423cf90 into main May 25, 2026
26 checks passed
@Evangelink Evangelink deleted the dev/amauryleve/fix-server-telemetry-init branch May 25, 2026 14:39
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