Skip to content

chore: Device/integration tests for mobile on .net10#4750

Merged
jamescrosswell merged 40 commits intomainfrom
net10_integration_tests
Feb 6, 2026
Merged

chore: Device/integration tests for mobile on .net10#4750
jamescrosswell merged 40 commits intomainfrom
net10_integration_tests

Conversation

@jamescrosswell
Copy link
Collaborator

Resolves #4744

#skip-changelog

@codecov
Copy link

codecov bot commented Nov 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.85%. Comparing base (dc9a036) to head (30cd0f6).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4750   +/-   ##
=======================================
  Coverage   73.85%   73.85%           
=======================================
  Files         483      483           
  Lines       17578    17578           
  Branches     3464     3464           
=======================================
+ Hits        12982    12983    +1     
+ Misses       3742     3741    -1     
  Partials      854      854           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jamescrosswell
Copy link
Collaborator Author

jamescrosswell commented Nov 21, 2025

Tricky... locally everything passes for me:
image

However in CI we've got 2 tests failing in Debug and 2 tests failing in Release:

...
2025-11-20T03:50:51.4905577Z ##[error][-] MAUI app (net10.0, Release).Native crash (Release) 21.13s (21.12s|3ms)�[0m
2025-11-20T03:50:51.4916597Z ##[group]Message�[0m
2025-11-20T03:50:52.4056556Z Expected a collection with size 1, but got collection with size 25
2025-11-20T03:50:52.7693005Z at <ScriptBlock>, /home/runner/work/sentry-dotnet/sentry-dotnet/integration-test/android.Tests.ps1:170�[0m
...
025-11-20T03:53:44.9710461Z ##[error][-] MAUI app (net10.0, Debug).Java crash (Debug) 10.9s (10.9s|1ms)�[0m
2025-11-20T03:53:44.9723309Z ##[group]Message�[0m,
2025-11-20T03:53:45.0186641Z Expected a collection with size 1, but got collection with size 2
2025-11-20T04:01:08.0804390Z at $result.Envelopes() | Should -HaveCount 1, /home/runner/work/sentry-dotnet/sentry-dotnet/integration-test/android.Tests.ps1:156�[0m
...
2025-11-20T03:58:20.3428226Z ##[error][-] MAUI app (net10.0, Release).Native crash (Release) 22.23s (22.23s|3ms)�[0m
2025-11-20T03:58:20.3429986Z ##[group]Message�[0m
2025-11-20T03:58:21.0057104Z Expected a collection with size 1, but got collection with size 28
2025-11-20T03:50:52.7693005Z at <ScriptBlock>, /home/runner/work/sentry-dotnet/sentry-dotnet/integration-test/android.Tests.ps1:170�[0m
...
2025-11-20T04:01:08.0369087Z ##[error][-] MAUI app (net10.0, Debug).Java crash (Debug) 9.43s (9.43s|1ms)�[0m
2025-11-20T04:01:08.0387771Z ##[group]Message�[0m
2025-11-20T04:01:08.0683949Z Expected a collection with size 1, but got collection with size 2
2025-11-20T04:01:08.0804390Z at $result.Envelopes() | Should -HaveCount 1, /home/runner/work/sentry-dotnet/sentry-dotnet/integration-test/android.Tests.ps1:156�[0m
...

Looking at the 2 envelopes received for the Java crashes (java_received.json) the only difference is the timestamp:
image

... so it looks like we're getting duplicate envelopes being sent for some reason
(but only on CI of course) 😕

@jamescrosswell
Copy link
Collaborator Author

@supervacuus wondering if you might have some insights. When bumping to .NET 10, our Android integration tests fail when creating a native crash...

2025-11-26T00:27:34.1540247Z Expected a collection with size 1, but got collection with size 16

Basically we have a single crash, so we're expecting a single envelope... but instead we get loads of envelopes (from sentry.native). We don't see the same behaviour in .net 9 (those tests pass fine)... so maybe a change in behaviour in terms of how .net 10 wraps signals 🤷🏻 although, if so, not one that's documented in the release notes. It's not always 16 envelopes - in previous runs it's been 26 or 28 etc. so basically just "way more than expected".

I can't reproduce this locally - it only happens to us in CI (which makes it pretty tricky to analyse).

It looks like maybe there are some tests that are already relevant in the native repo, so I created a PR to bump these to .NET 10 to see if we see the same issue there... although those are run on Linux Alpine (not Android) so not necessarily expecting the same results:

@supervacuus
Copy link

supervacuus commented Nov 26, 2025

Hi @jamescrosswell 👋

Basically we have a single crash, so we're expecting a single envelope... but instead we get loads of envelopes (from sentry.native). We don't see the same behaviour in .net 9 (those tests pass fine)... so maybe a change in behaviour in terms of how .net 10 wraps signals 🤷🏻 although, if so, not one that's documented in the release notes. It's not always 16 envelopes - in previous runs it's been 26 or 28 etc. so basically just "way more than expected".

From what I have seen over the last year in the .NET runtime's "documentation" on signal usage, I would be surprised if a change in behavior in that area made its way into the release notes.

I don't have an immediate idea and it is rather hard to follow for me, because i don't know what your test does and which of those outputs are relevant.

However, intuitively, a variable number of envelopes rather than one looks like a signal loop (typically caused by an abort(), because it resets the signal mask before it raises a SIGABRT), where some function after serializing the envelope causes a crash in the handler.

But it's really hard to say for me from what I know about your tests. It would be interesting to see all envelopes rather than just their count.

I can't reproduce this locally - it only happens to us in CI (which makes it pretty tricky to analyse).

But does it repro on CI stably? Would it be possible to actions/upload-artifact the entire envelope cache? The JSON printed in the logs only shows a stackrace with a SIGILL and a single frame from the crash() function libsentrysupplemental.so.

It looks like maybe there are some tests that are already relevant in the native repo, so I created a PR to bump these to .NET 10 to see if we see the same issue there... although those are run on Linux Alpine (not Android) so not necessarily expecting the same results:

getsentry/sentry-native#1457

Yes, the .NET tests fail with that bump, but likely due to .NET 10 being an unsupported target (see my response).

I would also ping @jpnurmi on this topic.

@jamescrosswell
Copy link
Collaborator Author

jamescrosswell commented Nov 27, 2025

I would also ping @jpnurmi on this topic.

Yes normally. He's unfortunately unavailable until next year 😢

I don't have an immediate idea and it is rather hard to follow for me, because i don't know what your test does and which of those outputs are relevant.

That's fair... JP actually wrote the tests. They're supposed to be high level simple integration tests in pester/powershell that compile a .net app and run it, passing in an argument that determines what the app should do. For example, in the test that's failing here, the argument is "Native", which just means the app should throw a native exception. That will crash the app, so the test then runs the app (which crashes) then runs the app again (to ensure any crashes dumped to disk get handled) then checks to make sure an envelope containing the expected event was sent/received by the fake sentry server.

a variable number of envelopes rather than one looks like a signal loop (typically caused by an abort(), because it resets the signal mask before it raises a SIGABRT), where some function after serializing the envelope causes a crash in the handler.

Hm, that gives me some clues. After each test, the app gets shut down with this. That should shut down Sentry before calling KillProcess, but I think I see an issue with the implementation for cascading shutdown to other SDKs here... in the case of Android and iOS there is no cascading so the Java SDK and it's embedded Native SDK don't get explicitly shutdown.

I'll dig into that and report back - thanks @supervacuus 🙏🏻

@jamescrosswell
Copy link
Collaborator Author

So I tried cascading the SDK shutdown to the Java SDK:

JavaSdk.Sentry.Close();

Unfortunately the Java SDK also doesn't cascade this to the instance of the native SDK 😢
https://github.com/getsentry/sentry-java/blob/fc5ccaf5844ae029d93c566b6fd1b4f5c2e4da83/sentry/src/main/java/io/sentry/Sentry.java#L715-L723

I guess it would be possible to rectify that in the Java SDK but that would require a series of new releases etc. I'll see if I can find an alternative workaround.

@jamescrosswell
Copy link
Collaborator Author

@Flash0ver in the latest test runs we're seeing:

Error: [-] MAUI app (net10.0, Release).Null reference exception (Release) 7.58s (7.57s|4ms)
Expected string '"type":"SIGSEGV"' to match no elements in collection

However when I run the same code in a sample application, I don't see the same behaviour, so I'm pretty sure this is as a result of the difficulty in finding a way to shut the app down in a way that does't create a signal loop and lots of other unrelated exceptions that get captured by the native client.

One possible "proper fix" would be to cascades the SDK shutdown logic, but I don't want to delay the version 6 release in order to build that so I think we park this PR for the time being and circle back post v6 release (perhaps in the new year when JP is back on deck).

@jpnurmi
Copy link
Collaborator

jpnurmi commented Jan 5, 2026

Hey, I have a fix coming up for duplicate Java events:

The SIGILL loop is still a mystery. It doesn't seem to be related to Process.KillProcess() - the same happens even with Process.KillProcess() removed.

@jpnurmi
Copy link
Collaborator

jpnurmi commented Jan 9, 2026

Good news. Both issues are in the test infrastructure, and fixes are on the way.

The SIGILL issue is luckily not a signal loop. Notice how the envelopes are sent at roughly 1s intervals. It is caused by the test app getting automatically relaunched because we trigger crashes a bit too early:

@jamescrosswell
Copy link
Collaborator Author

Good news. Both issues are in the test infrastructure, and fixes are on the way.

The SIGILL issue is luckily not a signal loop. Notice how the envelopes are sent at roughly 1s intervals. It is caused by the test app getting automatically relaunched because we trigger crashes a bit too early:

Awesome, thanks @jpnurmi - I'm back on deck now as well.

So once those two issues have been resolved, we could reopen this PR?

Copy link
Collaborator

@jpnurmi jpnurmi left a comment

Choose a reason for hiding this comment

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

what about ios integration tests?

@jamescrosswell
Copy link
Collaborator Author

what about ios integration tests?

That was going to be next yeah... wanted to get Android going first though, since it's typically easier.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<!-- Pin target iOS version so that our tests don't break when new versions of Xcode are released.
'netX.0-ios' resolves the latest version of the iOS SDK otherwise. -->
<TargetPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">18.0</TargetPlatformVersion>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could leave this in there (bump to 26.2 of course)... that would be consistent with what we've done for the IntegrationTestApp

Copy link
Member

Choose a reason for hiding this comment

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

follow-up: #4895

@jamescrosswell jamescrosswell changed the title Device/integration tests for mobile on .net10 chore: Device/integration tests for mobile on .net10 Feb 5, 2026
@jamescrosswell jamescrosswell marked this pull request as ready for review February 5, 2026 10:19
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<!-- https://github.com/advisories/GHSA-5f2m-466j-3848 -->
<PackageReference Include="System.Private.Uri" Version="4.3.2"/>
</ItemGroup>
Copy link

Choose a reason for hiding this comment

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

Security package condition will never match target framework

Medium Severity

The ItemGroup condition '$(TargetFramework)' == 'net9.0' will never match because the project's target frameworks are net9.0-android, net10.0-android, and net10.0-ios. The exact string net9.0 never appears as a target framework. This means the security fix for GHSA-5f2m-466j-3848 (System.Private.Uri package reference) will never be included. The condition should use $(TargetFramework.StartsWith('net9')) to match platform-specific TFMs, consistent with patterns used elsewhere in the codebase like Sentry.Bindings.Android.csproj.

Fix in Cursor Fix in Web

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Seems this section is redundant now... when I tweaked the condition per the suggestion above I got:

error NU1510: Warning As Error: PackageReference System.Private.Uri will not be pruned. Consider removing this package from your dependencies, as it is likely unnecessary.

I've removed it altogether.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link
Member

@Flash0ver Flash0ver left a comment

Choose a reason for hiding this comment

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

🤘

Comment on lines +5 to +8
<!-- Pin target iOS version so that our tests don't break when new versions of Xcode are released.
'netX.0-ios' resolves the latest version of the iOS SDK otherwise.
-->
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('OSX'))">$(TargetFrameworks);net10.0-ios26.2</TargetFrameworks>
Copy link
Member

Choose a reason for hiding this comment

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

follow-up: #4895

Comment on lines +15 to +17
# Note: we can't run against net10 and net9 becaus .NET 10 requires Xcode 26.2 and .NET 9 requires Xcode 26.0.
# The macOS GitHub Actions runners only have Xcode 26.1+ installed and no support for Xcode 26.2 is planned for
# net9.0-ios: https://github.com/dotnet/macios/issues/24199#issuecomment-3819021247
Copy link
Member

Choose a reason for hiding this comment

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

follow-up: #4895

Comment on lines +5 to +9
<!-- Note: we can't run against net9-ios because .NET 10 requires Xcode 26.2 and .NET 9 requires Xcode 26.0.
The macOS GitHub Actions runners only have Xcode 26.1+ installed and no support for Xcode 26.2 is planned for
net9.0-ios: https://github.com/dotnet/macios/issues/24199#issuecomment-3819021247
-->
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('OSX'))">$(TargetFrameworks);net10.0-ios</TargetFrameworks>
Copy link
Member

Choose a reason for hiding this comment

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

follow-up: #4895

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<!-- Pin target iOS version so that our tests don't break when new versions of Xcode are released.
'netX.0-ios' resolves the latest version of the iOS SDK otherwise. -->
<TargetPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">18.0</TargetPlatformVersion>
Copy link
Member

Choose a reason for hiding this comment

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

follow-up: #4895

@jamescrosswell jamescrosswell merged commit 863ee6a into main Feb 6, 2026
56 of 58 checks passed
@jamescrosswell jamescrosswell deleted the net10_integration_tests branch February 6, 2026 04:01
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.

MAUI/Mobile integration tests for .NET 10

4 participants