-
-
Notifications
You must be signed in to change notification settings - Fork 138
fix: skip Ctrl+C handling where Console.CancelKeyPress is unsupported #6889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
thomhurst
merged 22 commits into
thomhurst:main
from
glennawatson:fix/cancelkeypress-unsupported-platforms
Sep 26, 2026
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
0e2dd7c
fix: skip Ctrl+C handling where Console.CancelKeyPress is unsupported
glennawatson 382603c
ci: execute a shared TUnit smoke test on niche .NET platforms
thomhurst f6d3bfe
ci: reuse runner Android tools and configure Apple smoke launches
thomhurst b3d55ea
ci: run Apple smoke tests on x64 simulators and invoke Catalyst directly
thomhurst 1f2ee3e
ci: pass Catalyst test arguments through the platform launcher
thomhurst 6b3937a
ci: bundle Apple interpreter dependencies and verify application comp…
thomhurst 7475c3c
ci: quote the Apple completion check as a YAML block
thomhurst 4a2d65b
ci: write Catalyst test results inside its sandbox container
thomhurst b457888
ci: wait for Apple simulators to finish booting before installing tests
thomhurst 6cd356a
ci: execute Apple smoke apps directly with native platform tools
thomhurst 74cb469
ci: keep Catalyst reports within its writable sandbox
thomhurst c6d0c1c
ci: capture native Catalyst output and WASI failure artifacts
thomhurst 567a954
ci: disable external report writes in the Catalyst sandbox
thomhurst adf7142
fix: align console signal annotations with platform guards
thomhurst 1f2364a
ci: run WASI smoke test on .NET 11
thomhurst e764e45
ci: use .NET 11 Apple SDK tests on ARM64 runners
thomhurst 0d40693
ci: use .NET 11 SDK packaging and CoreCLR for mobile smoke tests
thomhurst 61a9128
ci: adapt smoke launches to .NET 11 SDK defaults
thomhurst 22f304b
ci: publish the .NET 11 browser app and correct Apple launch paths
thomhurst 2bc5cfb
ci: clear the unused UIKit context before the generated test entry point
thomhurst 3ae2f37
ci: provide simulator test reports through normal TUnit configuration
thomhurst 3fa5ea9
ci: run simulator apps with the installed simctl and verify TRX results
thomhurst File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| name: Platform smoke tests | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [main] | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| smoke: | ||
| name: ${{ matrix.platform }} smoke test | ||
| runs-on: ${{ matrix.os }} | ||
| timeout-minutes: 30 | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - platform: Browser | ||
| os: ubuntu-latest | ||
| workload: wasm-tools | ||
| - platform: Android | ||
| os: ubuntu-latest | ||
| workload: android | ||
| - platform: iOS | ||
| os: macos-26 | ||
| workload: ios | ||
| device: iPhone 17 | ||
| simulator: iOS-26-5 | ||
| - platform: tvOS | ||
| os: macos-26 | ||
| workload: tvos | ||
| device: Apple TV | ||
| simulator: tvOS-26-5 | ||
| - platform: MacCatalyst | ||
| os: macos-26 | ||
| workload: maccatalyst | ||
| - platform: WASI | ||
| os: ubuntu-latest | ||
| workload: wasi-experimental | ||
| env: | ||
| DOTNET_CLI_TELEMETRY_OPTOUT: 1 | ||
| TESTINGPLATFORM_TELEMETRY_OPTOUT: 1 | ||
| SmokePlatform: ${{ matrix.platform }} | ||
| steps: | ||
| - uses: actions/checkout@v7.0.1 | ||
| - uses: actions/setup-dotnet@v6.0.0 | ||
| with: | ||
| dotnet-version: 11.0.100-rc.1.26425.128 | ||
| - uses: actions/cache@v6 | ||
| with: | ||
| path: ~/.nuget/packages | ||
| key: platform-smoke-${{ runner.os }}-${{ runner.arch }}-${{ matrix.platform }}-${{ hashFiles('global.json', 'Directory.Packages.props', 'tests/TUnit.PlatformSmoke/TUnit.PlatformSmoke.csproj') }} | ||
| restore-keys: platform-smoke-${{ runner.os }}-${{ runner.arch }}-${{ matrix.platform }}- | ||
| - name: Select the installed Xcode | ||
| if: runner.os == 'macOS' | ||
| run: sudo xcode-select --switch /Applications/Xcode_26.6.app | ||
| - name: Start the installed Apple simulator | ||
| if: matrix.platform == 'iOS' || matrix.platform == 'tvOS' | ||
| run: | | ||
| device=$(xcrun simctl list devices available --json | jq -er '.devices["com.apple.CoreSimulator.SimRuntime.${{ matrix.simulator }}"] | map(select(.name == "${{ matrix.device }}")) | first | .udid // error("Required preinstalled simulator is missing")') | ||
| xcrun simctl boot "$device" | ||
| echo "Device=$device" >> "$GITHUB_ENV" | ||
| - run: dotnet workload install ${{ matrix.workload }} | ||
| - name: Install XHarness | ||
| if: matrix.platform == 'Browser' | ||
| run: >- | ||
| dotnet tool install Microsoft.DotNet.XHarness.CLI --global | ||
| --version 10.0.0-prerelease.26471.3 | ||
| --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json | ||
| - name: Publish the browser smoke test | ||
| if: matrix.platform == 'Browser' | ||
| run: dotnet publish tests/TUnit.PlatformSmoke -c Debug | ||
| - name: Build the smoke test | ||
| if: matrix.platform != 'Browser' | ||
| run: dotnet build tests/TUnit.PlatformSmoke -c Debug | ||
| - name: Execute the TUnit smoke test in Chrome | ||
| if: matrix.platform == 'Browser' | ||
| run: >- | ||
| xharness wasm test-browser | ||
| --app=tests/TUnit.PlatformSmoke/bin/Debug/net11.0/publish/wwwroot | ||
| --browser=chrome --expected-exit-code=0 --timeout=00:02:00 | ||
| --output-directory=artifacts/platform-smoke/browser | ||
| - name: Enable KVM | ||
| if: matrix.platform == 'Android' | ||
| run: sudo chmod 666 /dev/kvm | ||
| - name: Execute the TUnit smoke test on Android | ||
| if: matrix.platform == 'Android' | ||
| uses: reactivecircus/android-emulator-runner@v2 | ||
| with: | ||
| api-level: 35 | ||
| arch: x86_64 | ||
| target: google_apis | ||
| disable-animations: true | ||
| script: | | ||
| mkdir -p artifacts/platform-smoke/Android | ||
| bash -o pipefail -c 'dotnet test --project "$GITHUB_WORKSPACE/tests/TUnit.PlatformSmoke/TUnit.PlatformSmoke.csproj" --no-build 2>&1 | tee artifacts/platform-smoke/Android/test.log' | ||
| - name: Wait for the Apple simulator | ||
| if: matrix.platform == 'iOS' || matrix.platform == 'tvOS' | ||
| timeout-minutes: 10 | ||
| run: | | ||
| xcrun simctl bootstatus "$Device" -b | ||
| - name: Execute the TUnit smoke test on Mac Catalyst | ||
| if: matrix.platform == 'MacCatalyst' | ||
| working-directory: tests/TUnit.PlatformSmoke | ||
| timeout-minutes: 10 | ||
| shell: bash | ||
| run: | | ||
| mkdir -p "$GITHUB_WORKSPACE/artifacts/platform-smoke/${{ matrix.platform }}" | ||
| dotnet test --project "$GITHUB_WORKSPACE/tests/TUnit.PlatformSmoke/TUnit.PlatformSmoke.csproj" --no-build --minimum-expected-tests 1 \ | ||
| 2>&1 | tee "$GITHUB_WORKSPACE/artifacts/platform-smoke/${{ matrix.platform }}/test.log" | ||
| - name: Execute the TUnit smoke test in the Apple simulator | ||
| if: matrix.platform == 'iOS' || matrix.platform == 'tvOS' | ||
| timeout-minutes: 5 | ||
| shell: bash | ||
| run: | | ||
| mkdir -p "artifacts/platform-smoke/${{ matrix.platform }}" | ||
| platform=$(echo "$SmokePlatform" | tr '[:upper:]' '[:lower:]') | ||
| app="tests/TUnit.PlatformSmoke/bin/Debug/net11.0-$platform/${platform}simulator-arm64/TUnit.PlatformSmoke.app" | ||
| xcrun simctl install "$Device" "$app" | ||
| container=$(xcrun simctl get_app_container "$Device" net.dot.TUnitSmoke data) | ||
| xcrun simctl launch --console "$Device" net.dot.TUnitSmoke --connection-mode=none \ | ||
| --app-arg=--minimum-expected-tests --app-arg=1 \ | ||
| --app-arg=--report-trx --app-arg=--report-trx-filename --app-arg=smoke.trx \ | ||
| --app-arg=--results-directory "--app-arg=$container/Documents/TestResults" \ | ||
| 2>&1 | tee "artifacts/platform-smoke/${{ matrix.platform }}/test.log" | ||
| test "$(xmllint --xpath 'boolean(/*[local-name()="TestRun"]/*[local-name()="ResultSummary"]/*[local-name()="Counters"][@total="1" and @passed="1" and @failed="0"])' "$container/Documents/TestResults/smoke.trx")" = true | ||
| - name: Collect Apple simulator test reports | ||
| if: always() && (matrix.platform == 'iOS' || matrix.platform == 'tvOS') | ||
| run: | | ||
| if container=$(xcrun simctl get_app_container "$Device" net.dot.TUnitSmoke data 2>/dev/null); then | ||
| if [[ -d "$container/Documents/TestResults" ]]; then | ||
| mkdir -p "artifacts/platform-smoke/${{ matrix.platform }}" | ||
| cp -R "$container/Documents/TestResults" "artifacts/platform-smoke/${{ matrix.platform }}/" | ||
| fi | ||
| fi | ||
| - uses: bytecodealliance/actions/wasmtime/setup@v1.1.3 | ||
| if: matrix.platform == 'WASI' | ||
| with: | ||
| version: v49.0.1 | ||
| - name: Execute the TUnit smoke test on WASI | ||
| if: matrix.platform == 'WASI' | ||
| working-directory: tests/TUnit.PlatformSmoke/bin/Debug/net11.0/wasi-wasm | ||
| shell: bash | ||
| run: | | ||
| mkdir -p "$GITHUB_WORKSPACE/artifacts/platform-smoke/WASI" | ||
| wasmtime run -S http --dir . dotnet.wasm TUnit.PlatformSmoke \ | ||
| 2>&1 | tee "$GITHUB_WORKSPACE/artifacts/platform-smoke/WASI/run.log" | ||
| - uses: actions/upload-artifact@v7.0.1 | ||
| if: always() | ||
| with: | ||
| name: platform-smoke-${{ matrix.platform }} | ||
| path: artifacts/platform-smoke | ||
| if-no-files-found: ignore | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #if ANDROID | ||
| using Android.App; | ||
| using Android.OS; | ||
| using Android.Runtime; | ||
|
|
||
| namespace TUnit.PlatformSmoke; | ||
|
|
||
| [Instrumentation(Name = "net.dot.TUnitSmoke.TestInstrumentation")] | ||
| public sealed class AndroidInstrumentation(IntPtr handle, JniHandleOwnership ownership) | ||
| : Instrumentation(handle, ownership) | ||
| { | ||
| public override void OnCreate(Bundle? arguments) | ||
| { | ||
| base.OnCreate(arguments); | ||
| Start(); | ||
| } | ||
|
|
||
| public override async void OnStart() | ||
| { | ||
| base.OnStart(); | ||
| using var result = new Bundle(); | ||
| try | ||
| { | ||
| var resultsDirectory = Path.Combine(Application.Context.GetExternalFilesDir(null)!.AbsolutePath, "TestResults"); | ||
| // Use the same generated entry point and registered hooks as every other platform. | ||
| var exitCode = await MicrosoftTestingPlatformEntryPoint.Main([ | ||
| "--minimum-expected-tests", "1", | ||
| "--report-trx", "--report-trx-filename", "smoke.trx", | ||
| "--results-directory", resultsDirectory | ||
| ]); | ||
| result.PutString("resultsPath", Path.Combine(resultsDirectory, "smoke.trx")); | ||
| if (exitCode != 0) | ||
| { | ||
| result.PutString("error", $"TUnit exited with code {exitCode}."); | ||
| } | ||
|
|
||
| Finish(exitCode == 0 ? Result.Ok : Result.Canceled, result); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| result.PutString("error", exception.ToString()); | ||
| Finish(Result.Canceled, result); | ||
| } | ||
| } | ||
| } | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #if IOS || TVOS || MACCATALYST | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| namespace TUnit.PlatformSmoke; | ||
|
|
||
| internal static class AppleInitialization | ||
| { | ||
| [ModuleInitializer] | ||
| internal static void Initialize() | ||
| { | ||
| // The Apple SDK installs a UIKit context before Main. This console-style | ||
| // test app has no UI event loop to execute captured async continuations. | ||
| SynchronizationContext.SetSynchronizationContext(null); | ||
| } | ||
| } | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| using TUnit.Assertions; | ||
| using TUnit.Core; | ||
|
|
||
| namespace TUnit.PlatformSmoke; | ||
|
|
||
| public class SmokeTest | ||
| { | ||
| [Test] | ||
| public async Task RunsOnTheExpectedPlatform() | ||
| { | ||
| await Task.Yield(); | ||
| await Assert.That(Environment.Version.Major).IsEqualTo(11); | ||
|
|
||
| #if BROWSER | ||
| await Assert.That(OperatingSystem.IsBrowser()).IsTrue(); | ||
| #elif ANDROID | ||
| await Assert.That(OperatingSystem.IsAndroid()).IsTrue(); | ||
| #elif IOS | ||
| await Assert.That(OperatingSystem.IsIOS()).IsTrue(); | ||
| #elif TVOS | ||
| await Assert.That(OperatingSystem.IsTvOS()).IsTrue(); | ||
| #elif MACCATALYST | ||
| await Assert.That(OperatingSystem.IsMacCatalyst()).IsTrue(); | ||
| #elif WASI | ||
| await Assert.That(OperatingSystem.IsWasi()).IsTrue(); | ||
| #endif | ||
| #if IOS || TVOS || MACCATALYST | ||
| await Assert.That(System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture) | ||
| .IsEqualTo(System.Runtime.InteropServices.Architecture.Arm64); | ||
| #endif | ||
| await Assert.That(new List<int> { 1, 2 }.Count).IsEqualTo(2); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| <Project> | ||
| <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" Condition="'$(SmokePlatform)' != 'Browser'" /> | ||
| <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.WebAssembly" Condition="'$(SmokePlatform)' == 'Browser'" /> | ||
| <Import Project="../../eng/TestProject.props" /> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFrameworks /> | ||
| <TargetFramework>net11.0</TargetFramework> | ||
| <TargetFramework Condition="'$(SmokePlatform)' == 'Android'">net11.0-android</TargetFramework> | ||
| <TargetFramework Condition="'$(SmokePlatform)' == 'iOS'">net11.0-ios</TargetFramework> | ||
| <TargetFramework Condition="'$(SmokePlatform)' == 'tvOS'">net11.0-tvos</TargetFramework> | ||
| <TargetFramework Condition="'$(SmokePlatform)' == 'MacCatalyst'">net11.0-maccatalyst</TargetFramework> | ||
| <EnableTUnitPolyfills>false</EnableTUnitPolyfills> | ||
| <GenerateTestingPlatformEntryPoint>true</GenerateTestingPlatformEntryPoint> | ||
| </PropertyGroup> | ||
|
|
||
| <PropertyGroup Condition="'$(SmokePlatform)' == 'Android' or '$(SmokePlatform)' == 'iOS' or '$(SmokePlatform)' == 'tvOS' or '$(SmokePlatform)' == 'MacCatalyst'"> | ||
| <ApplicationId>net.dot.TUnitSmoke</ApplicationId> | ||
| <ApplicationTitle>TUnit smoke test</ApplicationTitle> | ||
| <ApplicationVersion>1</ApplicationVersion> | ||
| <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion> | ||
| <RuntimeIdentifier Condition="'$(SmokePlatform)' == 'Android'">android-x64</RuntimeIdentifier> | ||
| <RuntimeIdentifier Condition="'$(SmokePlatform)' == 'iOS'">iossimulator-arm64</RuntimeIdentifier> | ||
| <RuntimeIdentifier Condition="'$(SmokePlatform)' == 'tvOS'">tvossimulator-arm64</RuntimeIdentifier> | ||
| <RuntimeIdentifier Condition="'$(SmokePlatform)' == 'MacCatalyst'">maccatalyst-arm64</RuntimeIdentifier> | ||
| <RunWithOpen>false</RunWithOpen> | ||
| <MtouchLink Condition="'$(SmokePlatform)' != 'Android'">None</MtouchLink> | ||
| </PropertyGroup> | ||
|
|
||
| <PropertyGroup Condition="'$(SmokePlatform)' == 'Android'"> | ||
| <AndroidUseInstrumentation>true</AndroidUseInstrumentation> | ||
| <AndroidPackageFormat>apk</AndroidPackageFormat> | ||
| <PublishTrimmed>false</PublishTrimmed> | ||
| </PropertyGroup> | ||
|
|
||
| <PropertyGroup Condition="'$(SmokePlatform)' == 'Browser' or '$(SmokePlatform)' == 'WASI'"> | ||
| <RuntimeFrameworkVersion>11.0.0-rc.1.26425.128</RuntimeFrameworkVersion> | ||
| <UseMonoRuntime>true</UseMonoRuntime> | ||
| <SelfContained>true</SelfContained> | ||
| <PublishTrimmed>false</PublishTrimmed> | ||
| </PropertyGroup> | ||
| <PropertyGroup Condition="'$(SmokePlatform)' == 'WASI'"> | ||
| <RuntimeIdentifier>wasi-wasm</RuntimeIdentifier> | ||
| <DefineConstants>$(DefineConstants);WASI</DefineConstants> | ||
| </PropertyGroup> | ||
| <PropertyGroup Condition="'$(SmokePlatform)' == 'Browser'"> | ||
| <RuntimeIdentifier>browser-wasm</RuntimeIdentifier> | ||
| <OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders> | ||
| <DefineConstants>$(DefineConstants);BROWSER</DefineConstants> | ||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="../../src/TUnit/TUnit.csproj" /> | ||
| </ItemGroup> | ||
| <Import Project="../../eng/TestProject.targets" /> | ||
| <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="'$(SmokePlatform)' != 'Browser'" /> | ||
| <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.WebAssembly" Condition="'$(SmokePlatform)' == 'Browser'" /> | ||
| </Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "commandLineOptions": { | ||
| "minimum-expected-tests": 1, | ||
| "report-trx": true, | ||
| "results-directory": "TestResults" | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.