Skip to content

Re-enable Microsoft.Extensions.Hosting shutdown functional coverage in CI and harden Helix/NET481 compatibility#128252

Draft
Copilot wants to merge 19 commits into
mainfrom
copilot/enable-functional-tests-on-hosting
Draft

Re-enable Microsoft.Extensions.Hosting shutdown functional coverage in CI and harden Helix/NET481 compatibility#128252
Copilot wants to merge 19 commits into
mainfrom
copilot/enable-functional-tests-on-hosting

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 15, 2026

Description

This PR re-enables Microsoft.Extensions.Hosting shutdown functional coverage in CI and hardens the tests for Helix/minimal Linux environments where source layout or common external tools may be unavailable, while also ensuring the updated shutdown signal path compiles for net481 test legs.

Changes Made

  • Reworked ShutdownTests deployment to run Microsoft.Extensions.Hosting.TestApp from deployed test output (AppContext.BaseDirectory) instead of source-project lookup.
  • Re-enabled Hosting functional tests in CI by removing the CI skip gating (IgnoreForCI) and the assembly-level ActiveIssue.
  • Hardened Unix process cleanup to tolerate missing pgrep and improve robustness of shutdown/termination paths in minimal environments.
  • Removed the direct dependency on spawning kill for SIGINT delivery in ShutdownTests by using libc kill(pid, SIGINT).
  • Fixed net481 compatibility in ShutdownTests by using Marshal.GetLastWin32Error() (instead of Marshal.GetLastPInvokeError()) for the P/Invoke error path, resolving Windows x86 Libraries_NET481 build failures.
  • Fixed a structural hazard where ExistingOutputApplicationPublisher returned a PublishedApplication rooted at AppContext.BaseDirectory, whose Dispose() would recursively delete the test output directory:
    • Made PublishedApplication.Dispose() virtual in the integration testing harness.
    • Added a BorrowedPublishedApplication nested class inside ExistingOutputApplicationPublisher that overrides Dispose() as a no-op, since the path is borrowed from test output and must not be deleted.
    • Removed PreservePublishedApplicationForDebugging = true from DeploymentParameters; the structural fix makes this flag unnecessary.
  • Added shutdown cleanup hardening to ensure process-termination flows wait for exit and avoid race conditions when asserting post-kill process state:
    • WaitForExitOrKill now waits up to 5 seconds after calling Kill() before accessing ExitCode, preventing InvalidOperationException race conditions.
    • KillProcessUnix uses kill -TERM for graceful termination (SIGTERM) instead of Process.Kill() (SIGKILL), allowing processes to perform cleanup before exiting.
  • Increased test timeouts from 60 seconds to 180 seconds (3 minutes) for startup and shutdown waits to handle stress/JIT-stress pipelines and slow Helix environments.

Validation

  • Baseline build completed successfully:
    • ./build.sh clr+libs -rc release
  • Targeted Hosting functional tests passed:
    • dotnet build /t:test ./tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj
  • Targeted net481 build validation passed:
    • dotnet build ./tests/FunctionalTests/Microsoft.Extensions.Hosting.Functional.Tests.csproj -p:TargetFramework=net481 -c Release
  • Security validation run:
    • codeql_checker executed for this change.

Copilot AI requested review from Copilot and removed request for Copilot May 15, 2026 12:32
Copilot AI linked an issue May 15, 2026 that may be closed by this pull request
@github-actions github-actions Bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 15, 2026
Copilot AI requested review from Copilot and removed request for Copilot May 15, 2026 13:03
Copilot AI changed the title [WIP] Fix FunctionalTests/TestApp on Extensions Hosting Re-enable Microsoft.Extensions.Hosting FunctionalTests/TestApp shutdown coverage May 15, 2026
Copilot AI requested a review from rosebyte May 15, 2026 13:07
@github-actions github-actions Bot added area-Extensions-Hosting and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 15, 2026
@rosebyte
Copy link
Copy Markdown
Member

@copilot , the shutdown tests are failing with this error on helix machines:

Comments
{ "HelixJobId": "bf5b8a6f-0bdd-40b3-9fbc-f0eec7148f40", "HelixWorkItemName": "Microsoft.Extensions.Hosting.Functional.Tests" }

Error message
System.IO.DirectoryNotFoundException : Could not find Microsoft.Extensions.Hosting.TestApp.csproj from base directory '/root/helix/work/workitem/e/'.

Stack trace
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.GetApplicationPath() in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 173
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ExecuteShutdownTest(String testName, String shutdownMechanic) in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 53
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ShutdownTestRun() in /_/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 35
--- End of stack trace from previous location ---

Copilot AI requested review from Copilot and removed request for Copilot May 18, 2026 11:55
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 18, 2026

@copilot , the shutdown tests are failing with this error on helix machines:

...

Fixed in b9cd702. I removed the source-tree lookup and switched the shutdown tests to run TestApp from the deployed test output (AppContext.BaseDirectory) using a custom ApplicationPublisher, so Helix no longer requires Microsoft.Extensions.Hosting.TestApp.csproj to exist in the workitem.

Copilot AI changed the title Re-enable Microsoft.Extensions.Hosting FunctionalTests/TestApp shutdown coverage Re-enable Microsoft.Extensions.Hosting FunctionalTests/TestApp shutdown coverage across local and Helix environments May 18, 2026
@rosebyte
Copy link
Copy Markdown
Member

@copilot , this time it failed with this error:

Test Failures (700 tests failed)
🔹 [All failing tests from runtime]

⚠️ 698 failing tests not displayed for this pipeline due to space limitations

❌ Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ShutdownTestRun [Console] [Details] [Artifacts] [0.70% failure rate]
[ 🚧 Create issue against infrastructure team] [ 📄 Create issue in this repo]
Failing Configuration
AzureLinux.3.0.ArmArch.Open
Exception Message
System.ComponentModel.Win32Exception : An error occurred trying to start process 'pgrep' with working directory '/root/helix/work/workitem/e'. No such file or directory
CallStack
at Microsoft.Win32.SafeHandles.SafeProcessHandle.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, IDictionary2 env, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, SafeFileHandle stdinHandle, SafeFileHandle stdoutHandle, SafeFileHandle stderrHandle, Boolean usesTerminal, SafeHandle[] inheritedHandles, Holder& waitStateHolder, Boolean throwOnNoExec) in /_/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs:line 369 at Microsoft.Win32.SafeHandles.SafeProcessHandle.StartCore(ProcessStartInfo startInfo, SafeFileHandle stdinHandle, SafeFileHandle stdoutHandle, SafeFileHandle stderrHandle, SafeHandle[] inheritedHandles, Holder& waitStateHolder) in /_/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs:line 213 at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo, SafeFileHandle stdinHandle, SafeFileHandle stdoutHandle, SafeFileHandle stderrHandle, SafeHandle[] inheritedHandles) in /_/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs:line 363 at System.Diagnostics.Process.Start() in /_/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs:line 1272 at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) in /_/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs:line 1383 at Microsoft.Extensions.Internal.ProcessExtensions.RunProcessAndWaitForExit(String fileName, String arguments, TimeSpan timeout, String& stdout) in /_/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 93 at Microsoft.Extensions.Internal.ProcessExtensions.GetAllChildIdsUnix(Int32 parentId, ISet1 children, TimeSpan timeout) in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 44
at Microsoft.Extensions.Internal.ProcessExtensions.KillTree(Process process, TimeSpan timeout) in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 33
at Microsoft.Extensions.Internal.ProcessExtensions.KillTree(Process process) in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 17
at Microsoft.Extensions.Hosting.IntegrationTesting.ApplicationDeployer.ShutDownIfAnyHostProcess(Process hostProcess) in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/ApplicationDeployer.cs:line 126
at Microsoft.Extensions.Hosting.IntegrationTesting.SelfHostDeployer.Dispose() in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/SelfHostDeployer.cs:line 179
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ExecuteShutdownTest(String testName, String shutdownMechanic) in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 107
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ShutdownTestRun() in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 34
--- End of stack trace from previous location ---
❌ Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ShutdownTestWaitForShutdown [Console] [Details] [Artifacts] [0.69% failure rate]
[ 🚧 Create issue against infrastructure team] [ 📄 Create issue in this repo]
Failing Configuration
AzureLinux.3.0.ArmArch.Open
Exception Message
System.ComponentModel.Win32Exception : An error occurred trying to start process 'pgrep' with working directory '/root/helix/work/workitem/e'. No such file or directory
CallStack
at Microsoft.Win32.SafeHandles.SafeProcessHandle.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, IDictionary2 env, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, SafeFileHandle stdinHandle, SafeFileHandle stdoutHandle, SafeFileHandle stderrHandle, Boolean usesTerminal, SafeHandle[] inheritedHandles, Holder& waitStateHolder, Boolean throwOnNoExec) in /_/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs:line 369 at Microsoft.Win32.SafeHandles.SafeProcessHandle.StartCore(ProcessStartInfo startInfo, SafeFileHandle stdinHandle, SafeFileHandle stdoutHandle, SafeFileHandle stderrHandle, SafeHandle[] inheritedHandles, Holder& waitStateHolder) in /_/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs:line 213 at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo, SafeFileHandle stdinHandle, SafeFileHandle stdoutHandle, SafeFileHandle stderrHandle, SafeHandle[] inheritedHandles) in /_/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs:line 363 at System.Diagnostics.Process.Start() in /_/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs:line 1272 at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) in /_/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs:line 1383 at Microsoft.Extensions.Internal.ProcessExtensions.RunProcessAndWaitForExit(String fileName, String arguments, TimeSpan timeout, String& stdout) in /_/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 93 at Microsoft.Extensions.Internal.ProcessExtensions.GetAllChildIdsUnix(Int32 parentId, ISet1 children, TimeSpan timeout) in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 44
at Microsoft.Extensions.Internal.ProcessExtensions.KillTree(Process process, TimeSpan timeout) in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 33
at Microsoft.Extensions.Internal.ProcessExtensions.KillTree(Process process) in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/ProcessExtensions.cs:line 17
at Microsoft.Extensions.Hosting.IntegrationTesting.ApplicationDeployer.ShutDownIfAnyHostProcess(Process hostProcess) in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/ApplicationDeployer.cs:line 126
at Microsoft.Extensions.Hosting.IntegrationTesting.SelfHostDeployer.Dispose() in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/IntegrationTesting/src/Deployers/SelfHostDeployer.cs:line 179
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ExecuteShutdownTest(String testName, String shutdownMechanic) in //src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 107
at Microsoft.AspNetCore.Hosting.FunctionalTests.ShutdownTests.ShutdownTestWaitForShutdown() in /
/src/libraries/Microsoft.Extensions.Hosting/tests/FunctionalTests/ShutdownTests.cs:line 41
--- End of stack trace from previous location ---

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

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 27, 2026 05:41
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

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings May 28, 2026 16:05
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

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

@@ -3,8 +3,6 @@
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetFrameworkCurrent)</TargetFrameworks>
<EnableDefaultItems>true</EnableDefaultItems>
Copilot AI changed the title Re-enable Microsoft.Extensions.Hosting FunctionalTests/TestApp shutdown coverage across local and Helix environments (including NET481 compatibility) Re-enable Microsoft.Extensions.Hosting shutdown functional coverage in CI and harden Helix/NET481 compatibility Jun 5, 2026
…fter Kill()

Co-authored-by: rosebyte <14963300+rosebyte@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 5, 2026 08:01
@rosebyte
Copy link
Copy Markdown
Member

rosebyte commented Jun 5, 2026

@copilot , you only addressed one of my comments, resolve all of them.

… 180s for stress environments

Co-authored-by: rosebyte <14963300+rosebyte@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 5, 2026 08:15
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jun 5, 2026

@copilot , you only addressed one of my comments, resolve all of them.

Fixed in f9172b4. I've addressed both remaining issues:

  1. KillProcessUnix now uses kill -TERM for graceful termination (SIGTERM) instead of Process.Kill() (SIGKILL)
  2. Test timeouts increased from 60 seconds to 180 seconds (3 minutes) for startup and shutdown waits to handle stress/JIT-stress Helix environments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable FunctionalTests/TestApp on Extensions Hosting

3 participants