From 46bbbfe90ad2e1a7f1913107a8bf94ebc249e45b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 13:56:08 +0200 Subject: [PATCH 01/34] WIP: iOS integration test --- .github/workflows/device-tests-ios.yml | 5 ++ samples/Sentry.Samples.Maui/MainPage.xaml.cs | 13 ++++ samples/Sentry.Samples.Maui/MauiProgram.cs | 5 +- scripts/ios-integration.Tests.ps1 | 82 ++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 scripts/ios-integration.Tests.ps1 diff --git a/.github/workflows/device-tests-ios.yml b/.github/workflows/device-tests-ios.yml index 0e118745cc..8eb2b5d199 100644 --- a/.github/workflows/device-tests-ios.yml +++ b/.github/workflows/device-tests-ios.yml @@ -43,6 +43,11 @@ jobs: if: steps.first-run.outcome == 'failure' run: pwsh scripts/device-test.ps1 ios -Run + - name: Integration Tests + uses: getsentry/github-workflows/sentry-cli/integration-test/@a5e409bd5bad4c295201cdcfe862b17c50b29ab7 # v2.14.1 + with: + path: scripts/ios-integration.Tests.ps1 + - name: Upload results if: success() || failure() uses: actions/upload-artifact@v4 diff --git a/samples/Sentry.Samples.Maui/MainPage.xaml.cs b/samples/Sentry.Samples.Maui/MainPage.xaml.cs index b82a13787d..8f774eef85 100644 --- a/samples/Sentry.Samples.Maui/MainPage.xaml.cs +++ b/samples/Sentry.Samples.Maui/MainPage.xaml.cs @@ -25,6 +25,19 @@ protected override void OnAppearing() NativeCrashBtn.IsVisible = false; #endif base.OnAppearing(); + +#pragma warning disable CS0618 + var crashTypeEnv = Environment.GetEnvironmentVariable("SENTRY_CRASH_TYPE"); + if (Enum.TryParse(crashTypeEnv, ignoreCase: true, out var crashType)) + { + SentrySdk.CauseCrash(crashType); + } + else if (crashTypeEnv.Equals("exit", StringComparison.OrdinalIgnoreCase)) + { + SentrySdk.Flush(); + Environment.Exit(0); + } +#pragma warning restore CS0618 } private void OnCounterClicked(object sender, EventArgs e) diff --git a/samples/Sentry.Samples.Maui/MauiProgram.cs b/samples/Sentry.Samples.Maui/MauiProgram.cs index 1a8a6a30a7..50bb940d59 100644 --- a/samples/Sentry.Samples.Maui/MauiProgram.cs +++ b/samples/Sentry.Samples.Maui/MauiProgram.cs @@ -30,9 +30,12 @@ public static MauiApp CreateMauiApp() options.MaxBreadcrumbs = 1000; // Be aware that screenshots may contain PII - options.AttachScreenshot = true; + // TODO: separate integration test app + // options.AttachScreenshot = true; options.Debug = true; + // TODO: separate integration test app + options.DiagnosticLevel = SentryLevel.Info; options.Experimental.EnableLogs = true; options.SampleRate = 1.0F; diff --git a/scripts/ios-integration.Tests.ps1 b/scripts/ios-integration.Tests.ps1 new file mode 100644 index 0000000000..81335c2e39 --- /dev/null +++ b/scripts/ios-integration.Tests.ps1 @@ -0,0 +1,82 @@ +# This file contains test cases for https://pester.dev/ +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' +. $PSScriptRoot/ios-simulator-utils.ps1 +. $PSScriptRoot/../integration-test/common.ps1 + +Describe 'MAUI app' { + It 'Produces the expected exceptions' { + $result = Invoke-SentryServer { + Param([string]$url) + + Push-Location $PSScriptRoot/../samples/Sentry.Samples.Maui + try + { + $tfm = "net9.0-ios18.0" + $target = "ios-simulator-64" + $arch = ($(uname -m) -eq 'arm64') ? 'arm64' : 'x64' + $rid = "iossimulator-$arch" + $udid = Get-IosSimulatorUdid -IosVersion '18.5' -Verbose + $dsn = $url.Replace('http://', 'http://key@') + '/0' + + Write-Host "::group::Build" + $env:SENTRY_DSN = $dsn + dotnet build Sentry.Samples.Maui.csproj ` + --configuration Release ` + --framework $tfm ` + --runtime $rid + | ForEach-Object { Write-Host $_ } + Write-Host '::endgroup::' + + Write-Host "::group::Install" + xharness apple install -v ` + --target $target ` + --app bin/Release/$tfm/$rid/Sentry.Samples.Maui.app ` + --device $udid ` + --output-directory=test_output + | ForEach-Object { Write-Host $_ } + Write-Host '::endgroup::' + + Write-Host "::group::Crash" + xharness apple just-run -v ` + --target $target ` + --app io.sentry.dotnet.samples.maui ` + --device $udid ` + --output-directory=test_output ` + --set-env SENTRY_DSN=$dsn ` + --set-env SENTRY_CRASH_TYPE=Managed + | ForEach-Object { Write-Host $_ } + Write-Host '::endgroup::' + + Write-Host "::group::Re-run" + xharness apple just-run -v ` + --target $target ` + --app io.sentry.dotnet.samples.maui ` + --device $udid ` + --output-directory=test_output ` + --set-env SENTRY_DSN=$dsn ` + --set-env SENTRY_CRASH_TYPE=Exit + | ForEach-Object { Write-Host $_ } + Write-Host '::endgroup::' + + Write-Host "::group::Uninstall" + xharness apple uninstall -v ` + --target $target ` + --app io.sentry.dotnet.samples.maui ` + --device $udid ` + --output-directory=test_output + | ForEach-Object { Write-Host $_ } + Write-Host '::endgroup::' + } + finally + { + Pop-Location + } + } + + $result.HasErrors() | Should -BeFalse + $result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.ApplicationException`"" + # TODO: add -Not after fixing redundant SIGABRT (#3954) + $result.Envelopes() | Should -AnyElementMatch "`"type`":`"SIGABRT`"" + } +} From 43b57c704b7b768c75e854025b3b6e95869201e1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 17:16:12 +0200 Subject: [PATCH 02/34] Split common.ps1 vs. setup.ps1 --- integration-test/cli.Tests.ps1 | 2 +- integration-test/common.ps1 | 161 ---------------------------- integration-test/runtime.Tests.ps1 | 2 +- integration-test/setup.ps1 | 162 +++++++++++++++++++++++++++++ scripts/ios-integration.Tests.ps1 | 4 +- 5 files changed, 166 insertions(+), 165 deletions(-) create mode 100644 integration-test/setup.ps1 diff --git a/integration-test/cli.Tests.ps1 b/integration-test/cli.Tests.ps1 index e3e91c0d12..e84ffc5c4e 100644 --- a/integration-test/cli.Tests.ps1 +++ b/integration-test/cli.Tests.ps1 @@ -1,7 +1,7 @@ # This file contains test cases for https://pester.dev/ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' -. $PSScriptRoot/common.ps1 +. $PSScriptRoot/setup.ps1 Describe 'Console apps () - normal build' -ForEach @( @{ framework = "net8.0" } diff --git a/integration-test/common.ps1 b/integration-test/common.ps1 index b7215fc87e..d7a79564d5 100644 --- a/integration-test/common.ps1 +++ b/integration-test/common.ps1 @@ -49,164 +49,3 @@ BeforeDiscovery { -Test ${function:ShouldAnyElementMatch} ` -SupportsArrayInput } - -AfterAll { - Pop-Location -} - -BeforeAll { - Push-Location $PSScriptRoot - $env:SENTRY_LOG_LEVEL = 'debug'; - - function GetSentryPackageVersion() - { - (Select-Xml -Path "$PSScriptRoot/../Directory.Build.props" -XPath "/Project/PropertyGroup/VersionPrefix").Node.InnerText - } - - function RegisterLocalPackage([string] $name) - { - $packageVersion = GetSentryPackageVersion - $packagePath = "$PSScriptRoot/../src/$name/bin/Release/$name.$packageVersion.nupkg" - if (-not (Test-Path env:CI)) - { - Write-Host "Packaging $name, expected output path: $packagePath" - dotnet pack "$PSScriptRoot/../src/$name" -c Release --nologo -p:Version=$packageVersion -p:IsPackable=true | ForEach-Object { Write-Host $_ } - if ($LASTEXITCODE -ne 0) - { - throw "Failed to package $name." - } - } - Write-Host "Using package $packagePath - $((Get-Item $packagePath).Length) bytes" - - dotnet nuget push $packagePath --source integration-test | ForEach-Object { Write-Host $_ } - if ($LASTEXITCODE -ne 0) - { - throw "Failed to add package $name to a local nuget source." - } - - # We need to remove the package from cache or it won't re resolved properly - Remove-Item -Path ~/.nuget/packages/$($name.ToLower())/$packageVersion -Recurse -Force -ErrorAction SilentlyContinue - } - - Remove-Item -Path "$PSScriptRoot/packages" -Recurse -Force -ErrorAction SilentlyContinue - New-Item -ItemType Directory -Path "$PSScriptRoot/packages" | Out-Null - RegisterLocalPackage 'Sentry' - - function RunDotnetWithSentryCLI([string] $action, [string]$project, [bool]$Symbols, [bool]$Sources, [string]$TargetFramework) - { - $rootDir = $PSScriptRoot - - $result = Invoke-SentryServer { - Param([string]$url) - Write-Host "::group::${action}ing $project" - try - { - dotnet $action $project -flp:logfile=build.log ` - -c Release ` - --nologo ` - --framework $TargetFramework ` - /p:SentryUploadSymbols=$Symbols ` - /p:SentryUploadSources=$Sources ` - /p:SentryOrg=org ` - /p:SentryProject=project ` - /p:SentryUrl=$url ` - /p:SentryAuthToken=dummy ` - | ForEach-Object { - if ($_ -match "^Time Elapsed ") - { - "Time Elapsed [value removed]" - } - elseif ($_ -match "\[[0-9/]+\]") - { - # Skip lines like `[102/103] Sentry.Samples.Maui.dll -> Sentry.Samples.Maui.dll.so` - } - else - { - "$_".Replace('\', '/').Replace($rootDir, '') - } - } - | ForEach-Object { - Write-Host " $_" - $_ - } - } - finally - { - Write-Host "::endgroup::" - } - } - - if ($action -eq "build") - { - $result.ScriptOutput | Should -Contain 'Build succeeded.' - } - elseif ($action -eq "publish") - { - $result.ScriptOutput | Should -AnyElementMatch "$((Get-Item $project).Basename) -> .*$project/bin/Release/$TargetFramework/.*/publish" - } - $result.ScriptOutput | Should -Not -AnyElementMatch "Preparing upload to Sentry for project 'Sentry'" - $result.HasErrors() | Should -BeFalse - $result - } - - function AddPackageReference([string] $projectPath, [string] $package) - { - Push-Location $projectPath - try - { - dotnet restore | ForEach-Object { Write-Host $_ } - if ($LASTEXITCODE -ne 0) - { - throw "Failed to restore the test app project." - } - - $packageVersion = GetSentryPackageVersion - dotnet add package $package --source $PSScriptRoot/packages --version $packageVersion --no-restore | ForEach-Object { Write-Host $_ } - if ($LASTEXITCODE -ne 0) - { - throw "Failed to add package dependency to the test app project." - } - } - finally - { - Pop-Location - } - } - function DotnetNew([string] $type, [string] $name, [string] $framework) - { - Remove-Item -Path $name -Recurse -Force -ErrorAction SilentlyContinue - dotnet new $type --output $name --framework $framework | ForEach-Object { Write-Host $_ } - if ($LASTEXITCODE -ne 0) - { - throw "Failed to create the test app '$name' from template '$type'." - } - - if ($type -eq 'maui') - { - @" - - - true - r8 - d8 - - -"@ | Out-File $name/Directory.Build.props - } - - if ($type -eq 'console') - { - AddPackageReference $name 'Sentry' - if (!$IsMacOS -or $framework -eq 'net8.0') - { - @" - - - true - - -"@ | Out-File $name/Directory.Build.props - } - } - } -} diff --git a/integration-test/runtime.Tests.ps1 b/integration-test/runtime.Tests.ps1 index 158890edc3..0263f11872 100644 --- a/integration-test/runtime.Tests.ps1 +++ b/integration-test/runtime.Tests.ps1 @@ -1,7 +1,7 @@ # This file contains test cases for https://pester.dev/ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' -. $PSScriptRoot/common.ps1 +. $PSScriptRoot/setup.ps1 Describe 'Console app NativeAOT ()' -ForEach @( @{ framework = 'net8.0' } diff --git a/integration-test/setup.ps1 b/integration-test/setup.ps1 new file mode 100644 index 0000000000..bf11658889 --- /dev/null +++ b/integration-test/setup.ps1 @@ -0,0 +1,162 @@ +. $PSScriptRoot/common.ps1 + +AfterAll { + Pop-Location +} + +BeforeAll { + Push-Location $PSScriptRoot + $env:SENTRY_LOG_LEVEL = 'debug'; + + function GetSentryPackageVersion() + { + (Select-Xml -Path "$PSScriptRoot/../Directory.Build.props" -XPath "/Project/PropertyGroup/VersionPrefix").Node.InnerText + } + + function RegisterLocalPackage([string] $name) + { + $packageVersion = GetSentryPackageVersion + $packagePath = "$PSScriptRoot/../src/$name/bin/Release/$name.$packageVersion.nupkg" + if (-not (Test-Path env:CI)) + { + Write-Host "Packaging $name, expected output path: $packagePath" + dotnet pack "$PSScriptRoot/../src/$name" -c Release --nologo -p:Version=$packageVersion -p:IsPackable=true | ForEach-Object { Write-Host $_ } + if ($LASTEXITCODE -ne 0) + { + throw "Failed to package $name." + } + } + Write-Host "Using package $packagePath - $((Get-Item $packagePath).Length) bytes" + + dotnet nuget push $packagePath --source integration-test | ForEach-Object { Write-Host $_ } + if ($LASTEXITCODE -ne 0) + { + throw "Failed to add package $name to a local nuget source." + } + + # We need to remove the package from cache or it won't re resolved properly + Remove-Item -Path ~/.nuget/packages/$($name.ToLower())/$packageVersion -Recurse -Force -ErrorAction SilentlyContinue + } + + Remove-Item -Path "$PSScriptRoot/packages" -Recurse -Force -ErrorAction SilentlyContinue + New-Item -ItemType Directory -Path "$PSScriptRoot/packages" | Out-Null + RegisterLocalPackage 'Sentry' + + function RunDotnetWithSentryCLI([string] $action, [string]$project, [bool]$Symbols, [bool]$Sources, [string]$TargetFramework) + { + $rootDir = $PSScriptRoot + + $result = Invoke-SentryServer { + Param([string]$url) + Write-Host "::group::${action}ing $project" + try + { + dotnet $action $project -flp:logfile=build.log ` + -c Release ` + --nologo ` + --framework $TargetFramework ` + /p:SentryUploadSymbols=$Symbols ` + /p:SentryUploadSources=$Sources ` + /p:SentryOrg=org ` + /p:SentryProject=project ` + /p:SentryUrl=$url ` + /p:SentryAuthToken=dummy ` + | ForEach-Object { + if ($_ -match "^Time Elapsed ") + { + "Time Elapsed [value removed]" + } + elseif ($_ -match "\[[0-9/]+\]") + { + # Skip lines like `[102/103] Sentry.Samples.Maui.dll -> Sentry.Samples.Maui.dll.so` + } + else + { + "$_".Replace('\', '/').Replace($rootDir, '') + } + } + | ForEach-Object { + Write-Host " $_" + $_ + } + } + finally + { + Write-Host "::endgroup::" + } + } + + if ($action -eq "build") + { + $result.ScriptOutput | Should -Contain 'Build succeeded.' + } + elseif ($action -eq "publish") + { + $result.ScriptOutput | Should -AnyElementMatch "$((Get-Item $project).Basename) -> .*$project/bin/Release/$TargetFramework/.*/publish" + } + $result.ScriptOutput | Should -Not -AnyElementMatch "Preparing upload to Sentry for project 'Sentry'" + $result.HasErrors() | Should -BeFalse + $result + } + + function AddPackageReference([string] $projectPath, [string] $package) + { + Push-Location $projectPath + try + { + dotnet restore | ForEach-Object { Write-Host $_ } + if ($LASTEXITCODE -ne 0) + { + throw "Failed to restore the test app project." + } + + $packageVersion = GetSentryPackageVersion + dotnet add package $package --source $PSScriptRoot/packages --version $packageVersion --no-restore | ForEach-Object { Write-Host $_ } + if ($LASTEXITCODE -ne 0) + { + throw "Failed to add package dependency to the test app project." + } + } + finally + { + Pop-Location + } + } + function DotnetNew([string] $type, [string] $name, [string] $framework) + { + Remove-Item -Path $name -Recurse -Force -ErrorAction SilentlyContinue + dotnet new $type --output $name --framework $framework | ForEach-Object { Write-Host $_ } + if ($LASTEXITCODE -ne 0) + { + throw "Failed to create the test app '$name' from template '$type'." + } + + if ($type -eq 'maui') + { + @" + + + true + r8 + d8 + + +"@ | Out-File $name/Directory.Build.props + } + + if ($type -eq 'console') + { + AddPackageReference $name 'Sentry' + if (!$IsMacOS -or $framework -eq 'net8.0') + { + @" + + + true + + +"@ | Out-File $name/Directory.Build.props + } + } + } +} diff --git a/scripts/ios-integration.Tests.ps1 b/scripts/ios-integration.Tests.ps1 index 81335c2e39..238885b1b7 100644 --- a/scripts/ios-integration.Tests.ps1 +++ b/scripts/ios-integration.Tests.ps1 @@ -76,7 +76,7 @@ Describe 'MAUI app' { $result.HasErrors() | Should -BeFalse $result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.ApplicationException`"" - # TODO: add -Not after fixing redundant SIGABRT (#3954) - $result.Envelopes() | Should -AnyElementMatch "`"type`":`"SIGABRT`"" + # TODO: fix redundant SIGABRT (#3954) + { $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"SIGABRT`"" } | Should -Throw } } From d79436c048b23579dca80e161510c8d71f3b2830 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 17:25:24 +0200 Subject: [PATCH 03/34] Fix empty --device argument --- scripts/ios-integration.Tests.ps1 | 37 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/scripts/ios-integration.Tests.ps1 b/scripts/ios-integration.Tests.ps1 index 238885b1b7..af2a3d9bee 100644 --- a/scripts/ios-integration.Tests.ps1 +++ b/scripts/ios-integration.Tests.ps1 @@ -8,6 +8,7 @@ Describe 'MAUI app' { It 'Produces the expected exceptions' { $result = Invoke-SentryServer { Param([string]$url) + $dsn = $url.Replace('http://', 'http://key@') + '/0' Push-Location $PSScriptRoot/../samples/Sentry.Samples.Maui try @@ -17,7 +18,17 @@ Describe 'MAUI app' { $arch = ($(uname -m) -eq 'arm64') ? 'arm64' : 'x64' $rid = "iossimulator-$arch" $udid = Get-IosSimulatorUdid -IosVersion '18.5' -Verbose - $dsn = $url.Replace('http://', 'http://key@') + '/0' + + $arguments = @( + "-v", + "--target=$target", + "--output-directory=test_output" + ) + if ($udid) { + $arguments += @("--device=$udid") + } else { + Write-Host "No suitable simulator found; proceeding without a specific --device" + } Write-Host "::group::Build" $env:SENTRY_DSN = $dsn @@ -29,42 +40,30 @@ Describe 'MAUI app' { Write-Host '::endgroup::' Write-Host "::group::Install" - xharness apple install -v ` - --target $target ` - --app bin/Release/$tfm/$rid/Sentry.Samples.Maui.app ` - --device $udid ` - --output-directory=test_output + xharness apple install $arguments ` + --app bin/Release/$tfm/$rid/Sentry.Samples.Maui.app | ForEach-Object { Write-Host $_ } Write-Host '::endgroup::' Write-Host "::group::Crash" - xharness apple just-run -v ` - --target $target ` + xharness apple just-run $arguments ` --app io.sentry.dotnet.samples.maui ` - --device $udid ` - --output-directory=test_output ` --set-env SENTRY_DSN=$dsn ` --set-env SENTRY_CRASH_TYPE=Managed | ForEach-Object { Write-Host $_ } Write-Host '::endgroup::' Write-Host "::group::Re-run" - xharness apple just-run -v ` - --target $target ` + xharness apple just-run $arguments ` --app io.sentry.dotnet.samples.maui ` - --device $udid ` - --output-directory=test_output ` --set-env SENTRY_DSN=$dsn ` --set-env SENTRY_CRASH_TYPE=Exit | ForEach-Object { Write-Host $_ } Write-Host '::endgroup::' Write-Host "::group::Uninstall" - xharness apple uninstall -v ` - --target $target ` - --app io.sentry.dotnet.samples.maui ` - --device $udid ` - --output-directory=test_output + xharness apple uninstall $arguments ` + --app io.sentry.dotnet.samples.maui | ForEach-Object { Write-Host $_ } Write-Host '::endgroup::' } From a916900aee7b8f3d29ca51cf8743b961e5026b18 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 17:55:45 +0200 Subject: [PATCH 04/34] Temp speed up --- .github/workflows/device-tests-ios.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/device-tests-ios.yml b/.github/workflows/device-tests-ios.yml index 8eb2b5d199..51f15abd0e 100644 --- a/.github/workflows/device-tests-ios.yml +++ b/.github/workflows/device-tests-ios.yml @@ -31,17 +31,17 @@ jobs: - name: Setup Environment uses: ./.github/actions/environment - - name: Build iOS Test App - run: pwsh ./scripts/device-test.ps1 ios -Build + # - name: Build iOS Test App + # run: pwsh ./scripts/device-test.ps1 ios -Build - - name: Run Tests - id: first-run - continue-on-error: true - run: pwsh scripts/device-test.ps1 ios -Run + # - name: Run Tests + # id: first-run + # continue-on-error: true + # run: pwsh scripts/device-test.ps1 ios -Run - - name: Retry Tests (if previous failed to run) - if: steps.first-run.outcome == 'failure' - run: pwsh scripts/device-test.ps1 ios -Run + # - name: Retry Tests (if previous failed to run) + # if: steps.first-run.outcome == 'failure' + # run: pwsh scripts/device-test.ps1 ios -Run - name: Integration Tests uses: getsentry/github-workflows/sentry-cli/integration-test/@a5e409bd5bad4c295201cdcfe862b17c50b29ab7 # v2.14.1 From 67fd41042e1cd8ef207127dd342db92d5fca567d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 18:05:12 +0200 Subject: [PATCH 05/34] Try BeforeAll --- scripts/ios-integration.Tests.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/ios-integration.Tests.ps1 b/scripts/ios-integration.Tests.ps1 index af2a3d9bee..5d88a44f13 100644 --- a/scripts/ios-integration.Tests.ps1 +++ b/scripts/ios-integration.Tests.ps1 @@ -1,10 +1,12 @@ # This file contains test cases for https://pester.dev/ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' -. $PSScriptRoot/ios-simulator-utils.ps1 . $PSScriptRoot/../integration-test/common.ps1 Describe 'MAUI app' { + BeforeAll { + . $PSScriptRoot/ios-simulator-utils.ps1 + } It 'Produces the expected exceptions' { $result = Invoke-SentryServer { Param([string]$url) From 83c30843d0dcdd7102572a69093cccdaaac0e3e2 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 18:09:06 +0200 Subject: [PATCH 06/34] Restore, retry, artifacts --- .github/workflows/device-tests-ios.yml | 29 +++++++++++++++++--------- scripts/ios-integration.Tests.ps1 | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/workflows/device-tests-ios.yml b/.github/workflows/device-tests-ios.yml index 51f15abd0e..6e0e5175da 100644 --- a/.github/workflows/device-tests-ios.yml +++ b/.github/workflows/device-tests-ios.yml @@ -31,19 +31,26 @@ jobs: - name: Setup Environment uses: ./.github/actions/environment - # - name: Build iOS Test App - # run: pwsh ./scripts/device-test.ps1 ios -Build + - name: Build iOS Test App + run: pwsh ./scripts/device-test.ps1 ios -Build - # - name: Run Tests - # id: first-run - # continue-on-error: true - # run: pwsh scripts/device-test.ps1 ios -Run + - name: Run Tests + id: first-test-run + continue-on-error: true + run: pwsh scripts/device-test.ps1 ios -Run - # - name: Retry Tests (if previous failed to run) - # if: steps.first-run.outcome == 'failure' - # run: pwsh scripts/device-test.ps1 ios -Run + - name: Retry Tests (if previous failed to run) + if: steps.first-test-run.outcome == 'failure' + run: pwsh scripts/device-test.ps1 ios -Run - name: Integration Tests + id: first-integration-test-run + uses: getsentry/github-workflows/sentry-cli/integration-test/@a5e409bd5bad4c295201cdcfe862b17c50b29ab7 # v2.14.1 + with: + path: scripts/ios-integration.Tests.ps1 + + - name: Retry Integration Tests (if previous failed to run) + if: steps.first-integration-test-run.outcome == 'failure' uses: getsentry/github-workflows/sentry-cli/integration-test/@a5e409bd5bad4c295201cdcfe862b17c50b29ab7 # v2.14.1 with: path: scripts/ios-integration.Tests.ps1 @@ -53,4 +60,6 @@ jobs: uses: actions/upload-artifact@v4 with: name: device-test-ios-results - path: test_output + path: | + test_output + integration_test_output diff --git a/scripts/ios-integration.Tests.ps1 b/scripts/ios-integration.Tests.ps1 index 5d88a44f13..23351d513f 100644 --- a/scripts/ios-integration.Tests.ps1 +++ b/scripts/ios-integration.Tests.ps1 @@ -24,7 +24,7 @@ Describe 'MAUI app' { $arguments = @( "-v", "--target=$target", - "--output-directory=test_output" + "--output-directory=integration_test_output" ) if ($udid) { $arguments += @("--device=$udid") From 6cc76965bffcc8795ba3f2bea7f499b3c93803a8 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 24 Sep 2025 21:40:19 +0200 Subject: [PATCH 07/34] Add test/Sentry.Maui.Device.IntegrationTestApp --- samples/Sentry.Samples.Maui/MainPage.xaml.cs | 13 - samples/Sentry.Samples.Maui/MauiProgram.cs | 5 +- scripts/ios-integration.Tests.ps1 | 25 +- .../App.xaml | 14 + .../App.xaml.cs | 14 + .../AppShell.xaml | 14 + .../AppShell.xaml.cs | 9 + .../Directory.Build.props | 2 + .../GlobalXmlns.cs | 2 + .../MainPage.xaml | 36 ++ .../MainPage.xaml.cs | 41 ++ .../MauiProgram.cs | 30 ++ .../Platforms/Android/AndroidManifest.xml | 6 + .../Platforms/Android/MainActivity.cs | 10 + .../Platforms/Android/MainApplication.cs | 15 + .../Android/Resources/values/colors.xml | 6 + .../Platforms/iOS/AppDelegate.cs | 9 + .../Platforms/iOS/Info.plist | 32 ++ .../Platforms/iOS/Program.cs | 15 + .../iOS/Resources/PrivacyInfo.xcprivacy | 51 ++ .../Properties/launchSettings.json | 8 + .../Resources/AppIcon/appicon.svg | 4 + .../Resources/AppIcon/appiconfg.svg | 8 + .../Resources/Fonts/OpenSans-Regular.ttf | Bin 0 -> 96932 bytes .../Resources/Fonts/OpenSans-Semibold.ttf | Bin 0 -> 100820 bytes .../Resources/Images/dotnet_bot.png | Bin 0 -> 93437 bytes .../Resources/Raw/AboutAssets.txt | 15 + .../Resources/Splash/splash.svg | 8 + .../Resources/Styles/Colors.xaml | 45 ++ .../Resources/Styles/Styles.xaml | 444 ++++++++++++++++++ ...ntry.Maui.Device.IntegrationTestApp.csproj | 56 +++ 31 files changed, 911 insertions(+), 26 deletions(-) create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/App.xaml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/App.xaml.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Directory.Build.props create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/GlobalXmlns.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/MainPage.xaml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/MainPage.xaml.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/MauiProgram.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/Android/AndroidManifest.xml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/Android/MainActivity.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/Android/MainApplication.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/Android/Resources/values/colors.xml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/iOS/AppDelegate.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/iOS/Info.plist create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/iOS/Program.cs create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Platforms/iOS/Resources/PrivacyInfo.xcprivacy create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Properties/launchSettings.json create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/AppIcon/appicon.svg create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/AppIcon/appiconfg.svg create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Fonts/OpenSans-Regular.ttf create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Fonts/OpenSans-Semibold.ttf create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Images/dotnet_bot.png create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Raw/AboutAssets.txt create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Splash/splash.svg create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Styles/Colors.xaml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Resources/Styles/Styles.xaml create mode 100644 test/Sentry.Maui.Device.IntegrationTestApp/Sentry.Maui.Device.IntegrationTestApp.csproj diff --git a/samples/Sentry.Samples.Maui/MainPage.xaml.cs b/samples/Sentry.Samples.Maui/MainPage.xaml.cs index 8f774eef85..b82a13787d 100644 --- a/samples/Sentry.Samples.Maui/MainPage.xaml.cs +++ b/samples/Sentry.Samples.Maui/MainPage.xaml.cs @@ -25,19 +25,6 @@ protected override void OnAppearing() NativeCrashBtn.IsVisible = false; #endif base.OnAppearing(); - -#pragma warning disable CS0618 - var crashTypeEnv = Environment.GetEnvironmentVariable("SENTRY_CRASH_TYPE"); - if (Enum.TryParse(crashTypeEnv, ignoreCase: true, out var crashType)) - { - SentrySdk.CauseCrash(crashType); - } - else if (crashTypeEnv.Equals("exit", StringComparison.OrdinalIgnoreCase)) - { - SentrySdk.Flush(); - Environment.Exit(0); - } -#pragma warning restore CS0618 } private void OnCounterClicked(object sender, EventArgs e) diff --git a/samples/Sentry.Samples.Maui/MauiProgram.cs b/samples/Sentry.Samples.Maui/MauiProgram.cs index 50bb940d59..1a8a6a30a7 100644 --- a/samples/Sentry.Samples.Maui/MauiProgram.cs +++ b/samples/Sentry.Samples.Maui/MauiProgram.cs @@ -30,12 +30,9 @@ public static MauiApp CreateMauiApp() options.MaxBreadcrumbs = 1000; // Be aware that screenshots may contain PII - // TODO: separate integration test app - // options.AttachScreenshot = true; + options.AttachScreenshot = true; options.Debug = true; - // TODO: separate integration test app - options.DiagnosticLevel = SentryLevel.Info; options.Experimental.EnableLogs = true; options.SampleRate = 1.0F; diff --git a/scripts/ios-integration.Tests.ps1 b/scripts/ios-integration.Tests.ps1 index 23351d513f..e2818ecf4e 100644 --- a/scripts/ios-integration.Tests.ps1 +++ b/scripts/ios-integration.Tests.ps1 @@ -12,7 +12,7 @@ Describe 'MAUI app' { Param([string]$url) $dsn = $url.Replace('http://', 'http://key@') + '/0' - Push-Location $PSScriptRoot/../samples/Sentry.Samples.Maui + Push-Location $PSScriptRoot/../test/Sentry.Maui.Device.IntegrationTestApp try { $tfm = "net9.0-ios18.0" @@ -26,47 +26,54 @@ Describe 'MAUI app' { "--target=$target", "--output-directory=integration_test_output" ) - if ($udid) { + if ($udid) + { $arguments += @("--device=$udid") - } else { + } + else + { Write-Host "No suitable simulator found; proceeding without a specific --device" } Write-Host "::group::Build" - $env:SENTRY_DSN = $dsn - dotnet build Sentry.Samples.Maui.csproj ` + dotnet build Sentry.Maui.Device.IntegrationTestApp.csproj ` --configuration Release ` --framework $tfm ` --runtime $rid | ForEach-Object { Write-Host $_ } + $LASTEXITCODE | Should -Be 0 Write-Host '::endgroup::' Write-Host "::group::Install" xharness apple install $arguments ` - --app bin/Release/$tfm/$rid/Sentry.Samples.Maui.app + --app bin/Release/$tfm/$rid/Sentry.Maui.Device.IntegrationTestApp.app | ForEach-Object { Write-Host $_ } + $LASTEXITCODE | Should -Be 0 Write-Host '::endgroup::' Write-Host "::group::Crash" xharness apple just-run $arguments ` - --app io.sentry.dotnet.samples.maui ` + --app io.sentry.dotnet.maui.device.integrationtestapp ` --set-env SENTRY_DSN=$dsn ` --set-env SENTRY_CRASH_TYPE=Managed | ForEach-Object { Write-Host $_ } + $LASTEXITCODE | Should -Be 0 Write-Host '::endgroup::' Write-Host "::group::Re-run" xharness apple just-run $arguments ` - --app io.sentry.dotnet.samples.maui ` + --app io.sentry.dotnet.maui.device.integrationtestapp ` --set-env SENTRY_DSN=$dsn ` --set-env SENTRY_CRASH_TYPE=Exit | ForEach-Object { Write-Host $_ } + $LASTEXITCODE | Should -Be 0 Write-Host '::endgroup::' Write-Host "::group::Uninstall" xharness apple uninstall $arguments ` - --app io.sentry.dotnet.samples.maui + --app io.sentry.dotnet.maui.device.integrationtestapp | ForEach-Object { Write-Host $_ } + $LASTEXITCODE | Should -Be 0 Write-Host '::endgroup::' } finally diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/App.xaml b/test/Sentry.Maui.Device.IntegrationTestApp/App.xaml new file mode 100644 index 0000000000..183709a1c8 --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/App.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/App.xaml.cs b/test/Sentry.Maui.Device.IntegrationTestApp/App.xaml.cs new file mode 100644 index 0000000000..ddab362000 --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/App.xaml.cs @@ -0,0 +1,14 @@ +namespace Sentry.Maui.Device.IntegrationTestApp; + +public partial class App : Application +{ + public App() + { + InitializeComponent(); + } + + protected override Window CreateWindow(IActivationState? activationState) + { + return new Window(new AppShell()); + } +} \ No newline at end of file diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml b/test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml new file mode 100644 index 0000000000..9fc01ffd1c --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml.cs b/test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml.cs new file mode 100644 index 0000000000..251f111be7 --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/AppShell.xaml.cs @@ -0,0 +1,9 @@ +namespace Sentry.Maui.Device.IntegrationTestApp; + +public partial class AppShell : Shell +{ + public AppShell() + { + InitializeComponent(); + } +} diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/Directory.Build.props b/test/Sentry.Maui.Device.IntegrationTestApp/Directory.Build.props new file mode 100644 index 0000000000..bbb7413d29 --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/Directory.Build.props @@ -0,0 +1,2 @@ + + diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/GlobalXmlns.cs b/test/Sentry.Maui.Device.IntegrationTestApp/GlobalXmlns.cs new file mode 100644 index 0000000000..19ce62e506 --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/GlobalXmlns.cs @@ -0,0 +1,2 @@ +[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/maui/global", "Sentry.Maui.Device.IntegrationTestApp")] +[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/maui/global", "Sentry.Maui.Device.IntegrationTestApp.Pages")] diff --git a/test/Sentry.Maui.Device.IntegrationTestApp/MainPage.xaml b/test/Sentry.Maui.Device.IntegrationTestApp/MainPage.xaml new file mode 100644 index 0000000000..77c2f2d30a --- /dev/null +++ b/test/Sentry.Maui.Device.IntegrationTestApp/MainPage.xaml @@ -0,0 +1,36 @@ + + + + + + + +