From 57b197c41acb93e06899509c46414ab3578eac5d Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Fri, 24 Oct 2025 10:40:50 +0300 Subject: [PATCH 01/49] Add inital integration testas implementation --- integration-test/.gitignore | 6 + integration-test/CMakeLists.txt | 42 ++++ integration-test/Integration.Tests.ps1 | 296 +++++++++++++++++++++++++ integration-test/TestConfig.ps1.in | 5 + 4 files changed, 349 insertions(+) create mode 100644 integration-test/.gitignore create mode 100644 integration-test/CMakeLists.txt create mode 100644 integration-test/Integration.Tests.ps1 create mode 100644 integration-test/TestConfig.ps1.in diff --git a/integration-test/.gitignore b/integration-test/.gitignore new file mode 100644 index 000000000..89320d7b8 --- /dev/null +++ b/integration-test/.gitignore @@ -0,0 +1,6 @@ +# CMake build artifacts +build/ +TestConfig.local.ps1 + +# Test outputs +output/ diff --git a/integration-test/CMakeLists.txt b/integration-test/CMakeLists.txt new file mode 100644 index 000000000..d505b98b1 --- /dev/null +++ b/integration-test/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.20) +project(SentryUnrealIntegrationTests NONE) + +# Only configure if environment variables are set +if(NOT DEFINED ENV{SENTRY_UNREAL_TEST_DSN} OR NOT DEFINED ENV{SENTRY_AUTH_TOKEN}) + if(DEFINED ENV{SENTRY_FORCE_CONFIGURE_INTEGRATION_TEST}) + message(WARNING "Environment variables SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN are not defined but SENTRY_FORCE_CONFIGURE_INTEGRATION_TEST is set.") + else() + message(STATUS "Skipping integration test configuration: SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN must be defined") + + # Delete config file so test script knows to skip + set(configFile "${CMAKE_CURRENT_SOURCE_DIR}/TestConfig.local.ps1") + if(EXISTS ${configFile}) + file(REMOVE ${configFile}) + endif() + + return() + endif() +endif() + +include(FetchContent) + +# Fetch PowerShell modules for Sentry API integration +FetchContent_Declare( + app-runner + GIT_REPOSITORY https://github.com/getsentry/app-runner.git + GIT_TAG 44583d2c37d666d7e9063814491ab475e1c6020b +) + +FetchContent_MakeAvailable(app-runner) + +# Generate test configuration with app-runner path +set(configFile "${CMAKE_CURRENT_SOURCE_DIR}/TestConfig.local.ps1") +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/TestConfig.ps1.in" + "${configFile}" + @ONLY +) + +message(STATUS "Integration test environment configured") +message(STATUS " app-runner path: ${app-runner_SOURCE_DIR}") +message(STATUS " Config file: ${configFile}") diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 new file mode 100644 index 000000000..ddaeb6a45 --- /dev/null +++ b/integration-test/Integration.Tests.ps1 @@ -0,0 +1,296 @@ +# Integration tests for Sentry Unreal SDK +# Requires: +# - Pre-built SentryPlayground application +# - Environment variables: SENTRY_UNREAL_TEST_DSN, SENTRY_AUTH_TOKEN + +param( + [Parameter(Mandatory=$true)] + [string]$AppPath, + + [ValidateSet('Win64', 'Linux')] + [string]$Platform = 'Win64' +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +BeforeAll { + # Check if environment is configured + $configFile = "$PSScriptRoot/TestConfig.local.ps1" + if (-not (Test-Path $configFile)) { + throw @" +Integration test environment not configured. + +Please run: + cd integration-test + cmake -B build -S . + +With environment variables: + SENTRY_UNREAL_TEST_DSN=https://... + SENTRY_AUTH_TOKEN=sntrys_... +"@ + } + + # Load configuration (provides $global:AppRunnerPath) + . $configFile + + # Import app-runner modules + . "$global:AppRunnerPath/import-modules.ps1" + + # Validate environment variables + $script:DSN = $env:SENTRY_UNREAL_TEST_DSN + $script:AuthToken = $env:SENTRY_AUTH_TOKEN + + if (-not $script:DSN -or -not $script:AuthToken) { + throw "Environment variables SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN must be set" + } + + # Connect to Sentry API + Write-Host "Connecting to Sentry API..." -ForegroundColor Yellow + Connect-SentryApi -DSN $script:DSN -ApiToken $script:AuthToken + + # Validate app path + if (-not (Test-Path $AppPath)) { + throw "Application not found at: $AppPath" + } + + # Create output directory + $script:OutputDir = "$PSScriptRoot/output" + if (-not (Test-Path $script:OutputDir)) { + New-Item -ItemType Directory -Path $script:OutputDir | Out-Null + } + + Write-Host "Test environment ready" -ForegroundColor Green + Write-Host " Platform: $Platform" -ForegroundColor Cyan + Write-Host " App: $AppPath" -ForegroundColor Cyan + Write-Host " Output: $script:OutputDir" -ForegroundColor Cyan +} + +Describe "Sentry Unreal Integration Tests ($Platform)" { + + Context "Crash Capture Tests" { + BeforeAll { + $script:CrashResult = $null + $script:CrashEvent = $null + + Write-Host "Running crash capture test..." -ForegroundColor Yellow + + # Prepare output files + $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' + $stdoutFile = "$script:OutputDir/$timestamp-crash-stdout.log" + $stderrFile = "$script:OutputDir/$timestamp-crash-stderr.log" + + # Build arguments + $args = @('-crash-capture', '-NullRHI', '-unattended') + + # Execute application based on platform + if ($Platform -eq 'Win64') { + $process = Start-Process -FilePath $AppPath -ArgumentList $args ` + -Wait -PassThru -NoNewWindow ` + -RedirectStandardOutput $stdoutFile ` + -RedirectStandardError $stderrFile + + $script:CrashResult = @{ + ExitCode = $process.ExitCode + Output = Get-Content $stdoutFile + Error = Get-Content $stderrFile + } + } else { + # Linux + chmod +x $AppPath 2>&1 | Out-Null + $output = & $AppPath @args 2>&1 + $output | Out-File $stdoutFile + + $script:CrashResult = @{ + ExitCode = $LASTEXITCODE + Output = $output + Error = @() + } + } + + # Save full output + $script:CrashResult | ConvertTo-Json -Depth 5 | Out-File "$script:OutputDir/$timestamp-crash-result.json" + + Write-Host "Crash test executed. Exit code: $($script:CrashResult.ExitCode)" -ForegroundColor Cyan + + # Parse event ID from output + $eventIds = Get-EventIds -AppOutput $script:CrashResult.Output -ExpectedCount 1 + + if ($eventIds -and $eventIds.Count -gt 0) { + Write-Host "Event ID captured: $($eventIds[0])" -ForegroundColor Cyan + + $crashId = $eventIds[0] + + # Fetch event from Sentry (with polling) + try { + $script:CrashEvent = Get-SentryTestEvent -TagName 'test.crash_id' -TagValue "$crashId" + Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green + } catch { + Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red + } + } else { + Write-Host "Warning: No event ID found in output" -ForegroundColor Yellow + } + } + + It "Should have non-zero exit code" { + $script:CrashResult.ExitCode | Should -Not -Be 0 + } + + It "Should output event ID" { + $eventIds = Get-EventIds -AppOutput $script:CrashResult.Output -ExpectedCount 1 + $eventIds | Should -Not -BeNullOrEmpty + $eventIds.Count | Should -Be 1 + } + + It "Should capture crash event in Sentry" { + $script:CrashEvent | Should -Not -BeNullOrEmpty + } + + It "Should have correct event type and platform" { + $script:CrashEvent.type | Should -Be 'error' + $script:CrashEvent.platform | Should -Be 'native' + } + + It "Should have exception information" { + $script:CrashEvent.exception | Should -Not -BeNullOrEmpty + $script:CrashEvent.exception.values | Should -Not -BeNullOrEmpty + } + + It "Should have stack trace" { + $exception = $script:CrashEvent.exception.values[0] + $exception.stacktrace | Should -Not -BeNullOrEmpty + $exception.stacktrace.frames | Should -Not -BeNullOrEmpty + } + + It "Should have user context" { + $script:CrashEvent.user | Should -Not -BeNullOrEmpty + $script:CrashEvent.user.username | Should -Be 'TestUser' + $script:CrashEvent.user.email | Should -Be 'user-mail@test.abc' + $script:CrashEvent.user.id | Should -Be '12345' + } + + It "Should have integration test tag" { + $tags = $script:CrashEvent.tags + ($tags | Where-Object { $_.key -eq 'test.suite' }).value | Should -Be 'integration' + } + + It "Should have breadcrumbs" { + $script:CrashEvent.breadcrumbs | Should -Not -BeNullOrEmpty + $script:CrashEvent.breadcrumbs.values | Should -Not -BeNullOrEmpty + } + } + + Context "Message Capture Tests" { + BeforeAll { + $script:MessageResult = $null + $script:MessageEvent = $null + + Write-Host "Running message capture test..." -ForegroundColor Yellow + + # Prepare output files + $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' + $stdoutFile = "$script:OutputDir/$timestamp-message-stdout.log" + $stderrFile = "$script:OutputDir/$timestamp-message-stderr.log" + + # Build arguments + $args = @('-message-capture', '-NullRHI', '-unattended') + + # Execute application based on platform + if ($Platform -eq 'Win64') { + $process = Start-Process -FilePath $AppPath -ArgumentList $args ` + -Wait -PassThru -NoNewWindow ` + -RedirectStandardOutput $stdoutFile ` + -RedirectStandardError $stderrFile + + $script:MessageResult = @{ + ExitCode = $process.ExitCode + Output = Get-Content $stdoutFile + Error = Get-Content $stderrFile + } + } else { + # Linux + $output = & $AppPath @args 2>&1 + $output | Out-File $stdoutFile + + $script:MessageResult = @{ + ExitCode = $LASTEXITCODE + Output = $output + Error = @() + } + } + + # Save full output + $script:MessageResult | ConvertTo-Json -Depth 5 | Out-File "$script:OutputDir/$timestamp-message-result.json" + + Write-Host "Message test executed. Exit code: $($script:MessageResult.ExitCode)" -ForegroundColor Cyan + + # Parse event ID from output + $eventIds = Get-EventIds -AppOutput $script:MessageResult.Output -ExpectedCount 1 + + if ($eventIds -and $eventIds.Count -gt 0) { + Write-Host "Event ID captured: $($eventIds[0])" -ForegroundColor Cyan + + # Fetch event from Sentry (with polling) + try { + $script:MessageEvent = Get-SentryTestEvent -EventId $eventIds[0] -TimeoutSeconds 300 + Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green + } catch { + Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red + } + } else { + Write-Host "Warning: No event ID found in output" -ForegroundColor Yellow + } + } + + It "Should exit cleanly" { + $script:MessageResult.ExitCode | Should -Be 0 + } + + It "Should output event ID" { + $eventIds = Get-EventIds -AppOutput $script:MessageResult.Output -ExpectedCount 1 + $eventIds | Should -Not -BeNullOrEmpty + $eventIds.Count | Should -Be 1 + } + + It "Should output TEST_RESULT with success" { + $testResultLine = $script:MessageResult.Output | Where-Object { $_ -match 'TEST_RESULT:' } + $testResultLine | Should -Not -BeNullOrEmpty + $testResultLine | Should -Match '"success"\s*:\s*true' + } + + It "Should capture message event in Sentry" { + $script:MessageEvent | Should -Not -BeNullOrEmpty + } + + It "Should have correct platform" { + $script:MessageEvent.platform | Should -Be 'native' + } + + It "Should have message content" { + $script:MessageEvent.message | Should -Not -BeNullOrEmpty + $script:MessageEvent.message | Should -Match 'Integration test message' + } + + It "Should have user context" { + $script:MessageEvent.user | Should -Not -BeNullOrEmpty + $script:MessageEvent.user.username | Should -Be 'TestUser' + } + + It "Should have integration test tag" { + $tags = $script:MessageEvent.tags + ($tags | Where-Object { $_.key -eq 'test.suite' }).value | Should -Be 'integration' + } + + It "Should have breadcrumbs" { + $script:MessageEvent.breadcrumbs | Should -Not -BeNullOrEmpty + $script:MessageEvent.breadcrumbs.values | Should -Not -BeNullOrEmpty + } + } +} + +AfterAll { + Write-Host "Disconnecting from Sentry API..." -ForegroundColor Yellow + Disconnect-SentryApi + Write-Host "Integration tests complete" -ForegroundColor Green +} diff --git a/integration-test/TestConfig.ps1.in b/integration-test/TestConfig.ps1.in new file mode 100644 index 000000000..84909101d --- /dev/null +++ b/integration-test/TestConfig.ps1.in @@ -0,0 +1,5 @@ +# Auto-generated test configuration +# This file is generated by CMake - do not edit manually + +# Path to the fetched app-runner repository root +$global:AppRunnerPath = "@app-runner_SOURCE_DIR@" From 295c089b366ab823c70a5cabddbf1ea76b15aa5b Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Fri, 24 Oct 2025 10:41:10 +0300 Subject: [PATCH 02/49] Fix event id log format in sample app --- .../SentryPlaygroundGameInstance.cpp | 25 +++++++++++++++---- .../SentryPlaygroundGameInstance.h | 3 +++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 63c28023c..08f4d8400 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -28,7 +28,7 @@ void USentryPlaygroundGameInstance::Init() void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) { - UE_LOG(LogSentrySample, Log, TEXT("Running integration test for command: %s\n"), CommandLine); + UE_LOG(LogSentrySample, Display, TEXT("Running integration test for command: %s\n"), CommandLine); USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); if (!SentrySubsystem) @@ -78,9 +78,9 @@ void USentryPlaygroundGameInstance::RunCrashTest() // Because we don't get the real crash event ID, create a fake one and set it as a tag // This tag is then used by integration test script in CI to fetch the event - FString EventId = FGuid::NewGuid().ToString(EGuidFormats::Digits); + FString EventId = FGuid::NewGuid().ToString(EGuidFormats::DigitsWithHyphens); - UE_LOG(LogSentrySample, Log, TEXT("EVENT_CAPTURED: %s\n"), *EventId); + UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *EventId); SentrySubsystem->SetTag(TEXT("test.crash_id"), EventId); @@ -93,7 +93,7 @@ void USentryPlaygroundGameInstance::RunMessageTest() FString EventId = SentrySubsystem->CaptureMessage(TEXT("Integration test message")); - UE_LOG(LogSentrySample, Log, TEXT("EVENT_CAPTURED: %s\n"), *EventId); + UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete")); } @@ -115,9 +115,24 @@ void USentryPlaygroundGameInstance::ConfigureTestContext() void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestName, bool Result, const FString& Message) { - UE_LOG(LogSentrySample, Log, TEXT("TEST_RESULT: {\"test\":\"%s\",\"success\":%s,\"message\":\"%s\"}\n"), + UE_LOG(LogSentrySample, Display, TEXT("TEST_RESULT: {\"test\":\"%s\",\"success\":%s,\"message\":\"%s\"}\n"), *TestName, Result ? TEXT("true") : TEXT("false"), *Message); // Close app after test is completed FGenericPlatformMisc::RequestExit(false); } + +FString USentryPlaygroundGameInstance::FormatEventIdWithHyphens(const FString& EventId) +{ + if (EventId.Len() == 32 && !EventId.Contains(TEXT("-"))) + { + return FString::Printf(TEXT("%s-%s-%s-%s-%s"), + *EventId.Mid(0, 8), + *EventId.Mid(8, 4), + *EventId.Mid(12, 4), + *EventId.Mid(16, 4), + *EventId.Mid(20, 12)); + } + + return EventId; +} diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h index 59f5672d2..636baeda3 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h @@ -27,4 +27,7 @@ class SENTRYPLAYGROUND_API USentryPlaygroundGameInstance : public UGameInstance void ConfigureTestContext(); void CompleteTestWithResult(const FString& TestName, bool Result, const FString& Message); + + /** Converts event ID to UUID format with hyphens (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) */ + static FString FormatEventIdWithHyphens(const FString& EventId); }; From 3330fa55792f2ee480dbae16069dffbb31c939a1 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Fri, 24 Oct 2025 15:18:48 +0300 Subject: [PATCH 03/49] Temp fix for empty even json props --- integration-test/Integration.Tests.ps1 | 118 ++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index ddaeb6a45..1d4d9b283 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -14,6 +14,120 @@ param( Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' +function Convert-HashtableToObject($item) { + if ($item -is [System.Collections.IDictionary]) { + $obj = [PSCustomObject]@{} + foreach ($key in $item.Keys) { + if ([string]::IsNullOrWhiteSpace($key)) { + Write-Warning "Removed property with empty name" + continue + } + $obj | Add-Member -NotePropertyName $key -NotePropertyValue (Convert-HashtableToObject $item[$key]) + } + return $obj + } elseif ($item -is [System.Collections.IEnumerable] -and -not ($item -is [string])) { + return @($item | ForEach-Object { Convert-HashtableToObject $_ }) + } else { + return $item + } +} + +function Get-MyTestEvent { + [CmdletBinding()] + param( + [Parameter()] + [string]$EventId, + + [Parameter()] + [string]$TagName, + + [Parameter()] + [string]$TagValue, + + [Parameter()] + [int]$TimeoutSeconds = 120 + ) + + if ($EventId) { + Write-Host "Fetching Sentry event by ID: $EventId" -ForegroundColor Yellow + $progressActivity = "Waiting for Sentry event $EventId" + } elseif ($TagName -and $TagValue) { + Write-Host "Fetching Sentry event by tag: $TagName=$TagValue" -ForegroundColor Yellow + $progressActivity = "Waiting for Sentry event with tag $TagName=$TagValue" + } else { + throw 'Must specify either EventId or both TagName and TagValue' + } + + $startTime = Get-Date + $endTime = $startTime.AddSeconds($TimeoutSeconds) + $lastError = $null + $elapsedSeconds = 0 + + try { + do { + $sentryEvent = $null + $elapsedSeconds = [int]((Get-Date) - $startTime).TotalSeconds + $percentComplete = [math]::Min(100, ($elapsedSeconds / $TimeoutSeconds) * 100) + + Write-Progress -Activity $progressActivity -Status "Elapsed: $elapsedSeconds/$TimeoutSeconds seconds" -PercentComplete $percentComplete + + try { + if ($EventId) { + # Find by event ID + $sentryEvent = Get-SentryEvent -EventId $EventId + } else { + # Find by tag + $result = Find-SentryEventByTag -TagName $TagName -TagValue $TagValue + $result.Count | Should -Be 1 + $sentryEvent = $result[0] + } + } catch { + $lastError = $_.Exception.Message + # Event not found yet, continue waiting + if ($EventId) { + Write-Debug "Event $EventId not found yet: $lastError" + } else { + Write-Debug "Event with tag $TagName=$TagValue not found yet: $lastError" + } + } + + if ($sentryEvent) { + # Convert from JSON if it's a raw string + if ($sentryEvent -is [string]) { + try { + $raw = $sentryEvent | ConvertFrom-Json -Depth 50 -AsHashTable + # Recursively convert hashtables to PSCustomObjects + $sentryEvent = Convert-HashtableToObject $raw + } catch { + Write-Host "Failed to parse JSON from Sentry event: $($_.Exception.Message)" -ForegroundColor Red + return + } + } + + Write-Host "Event $($sentryEvent.id) fetched from Sentry" -ForegroundColor Green + $entries = $sentryEvent.entries + $sentryEvent = $sentryEvent | Select-Object -ExcludeProperty 'entries' + foreach ($entry in $entries) { + $sentryEvent | Add-Member -MemberType NoteProperty -Name $entry.type -Value $entry.data -Force + } + $sentryEvent | ConvertTo-Json -Depth 10 | Out-File -FilePath (Get-OutputFilePath "event-$($sentryEvent.id).json") + return $sentryEvent + } + + Start-Sleep -Milliseconds 500 + $currentTime = Get-Date + } while ($currentTime -lt $endTime) + } finally { + Write-Progress -Activity $progressActivity -Completed + } + + if ($EventId) { + throw "Event $EventId not found in Sentry within $TimeoutSeconds seconds: $lastError" + } else { + throw "Event with tag $TagName=$TagValue not found in Sentry within $TimeoutSeconds seconds: $lastError" + } +} + BeforeAll { # Check if environment is configured $configFile = "$PSScriptRoot/TestConfig.local.ps1" @@ -231,9 +345,9 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { if ($eventIds -and $eventIds.Count -gt 0) { Write-Host "Event ID captured: $($eventIds[0])" -ForegroundColor Cyan - # Fetch event from Sentry (with polling) + # Fetch event from Sentry (with polling) using sanitized helper try { - $script:MessageEvent = Get-SentryTestEvent -EventId $eventIds[0] -TimeoutSeconds 300 + $script:MessageEvent = Get-MyTestEvent -EventId $eventIds[0] -TimeoutSeconds 300 Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green } catch { Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red From 4d6f4ed99a6fec0f1afcfb04f0906fde842a5721 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Fri, 24 Oct 2025 15:29:57 +0300 Subject: [PATCH 04/49] Clean up --- integration-test/Integration.Tests.ps1 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 1d4d9b283..97495ebe6 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -19,7 +19,6 @@ function Convert-HashtableToObject($item) { $obj = [PSCustomObject]@{} foreach ($key in $item.Keys) { if ([string]::IsNullOrWhiteSpace($key)) { - Write-Warning "Removed property with empty name" continue } $obj | Add-Member -NotePropertyName $key -NotePropertyValue (Convert-HashtableToObject $item[$key]) @@ -32,7 +31,7 @@ function Convert-HashtableToObject($item) { } } -function Get-MyTestEvent { +function Get-SentryUnrealTestEvent { [CmdletBinding()] param( [Parameter()] @@ -237,7 +236,7 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { # Fetch event from Sentry (with polling) try { - $script:CrashEvent = Get-SentryTestEvent -TagName 'test.crash_id' -TagValue "$crashId" + $script:CrashEvent = Get-SentryUnrealTestEvent -TagName 'test.crash_id' -TagValue "$crashId" Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green } catch { Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red @@ -347,7 +346,7 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { # Fetch event from Sentry (with polling) using sanitized helper try { - $script:MessageEvent = Get-MyTestEvent -EventId $eventIds[0] -TimeoutSeconds 300 + $script:MessageEvent = Get-SentryUnrealTestEvent -EventId $eventIds[0] Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green } catch { Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red From 6df02107fc2952f2827394e6d4fca9cddf7f26c8 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Fri, 24 Oct 2025 16:37:22 +0300 Subject: [PATCH 05/49] Fix function --- integration-test/Integration.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 97495ebe6..9c1942096 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -14,7 +14,7 @@ param( Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' -function Convert-HashtableToObject($item) { +function script:Convert-HashtableToObject($item) { if ($item -is [System.Collections.IDictionary]) { $obj = [PSCustomObject]@{} foreach ($key in $item.Keys) { @@ -31,7 +31,7 @@ function Convert-HashtableToObject($item) { } } -function Get-SentryUnrealTestEvent { +function script:Get-SentryUnrealTestEvent { [CmdletBinding()] param( [Parameter()] From c1c6d315bff07b1b109f631f4d83abaaa309a993 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 08:44:59 +0200 Subject: [PATCH 06/49] Add readme instructions for integration tests --- integration-test/README.md | 126 +++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 integration-test/README.md diff --git a/integration-test/README.md b/integration-test/README.md new file mode 100644 index 000000000..e54f3eb2d --- /dev/null +++ b/integration-test/README.md @@ -0,0 +1,126 @@ +# Sentry Unreal Integration Tests + +This directory contains integration tests for the Sentry Unreal SDK using Pester (PowerShell testing framework). + +## Prerequisites + +- **PowerShell 7+** (Core edition) +- **CMake 3.20+** +- **Pester 5+** - Install with: `Install-Module -Name Pester -Force -SkipPublisherCheck` +- **Pre-built SentryPlayground application** (from local build or CI artifact) +- **Environment variables**: + - `SENTRY_UNREAL_TEST_DSN` - Sentry test project DSN + - `SENTRY_AUTH_TOKEN` - Sentry API authentication token + +## Setup + +### 1. Configure Integration Test Environment + +Run CMake to download required PowerShell modules (app-runner): + +```bash +cd integration-test +cmake -B build -S . +``` + +This will: +- Download `app-runner` from GitHub (contains SentryApiClient and test utilities) +- Generate `TestConfig.local.ps1` with module paths + +**Note**: If environment variables are not set, CMake will skip configuration with a warning. Set them first: + +```bash +# Windows PowerShell +$env:SENTRY_UNREAL_TEST_DSN = "https://key@org.ingest.sentry.io/project" +$env:SENTRY_AUTH_TOKEN = "sntrys_your_token_here" + +# Linux/macOS +export SENTRY_UNREAL_TEST_DSN="https://key@org.ingest.sentry.io/project" +export SENTRY_AUTH_TOKEN="sntrys_your_token_here" +``` + +### 2. Get SentryPlayground Application + +#### Option A: Download from CI Artifacts + +1. Go to [GitHub Actions](https://github.com/getsentry/sentry-unreal/actions/workflows/ci.yml) +2. Find a successful workflow run +3. Download the appropriate artifact: + - `UE X.X sample build (Windows)` for Windows testing + - `UE X.X sample build (Linux)` for Linux testing +4. Extract to a known location + +#### Option B: Build Locally + +Follow the standard Unreal Engine build process for the [sample](./sample/) project. + +## Running Tests + +### Windows + +```powershell +# Ensure environment variables are set +$env:SENTRY_UNREAL_TEST_DSN = "https://..." +$env:SENTRY_AUTH_TOKEN = "sntrys_..." + +# Run tests +Invoke-Pester integration-test/Integration.Tests.ps1 + +# You will be prompted for test application path +# Supply values for the following parameters: +# AppPath: path/to/SentryPlayground.exe +``` + +### Linux + +```bash +# Ensure environment variables are set +export SENTRY_UNREAL_TEST_DSN="https://..." +export SENTRY_AUTH_TOKEN="sntrys_..." + +# Run tests +pwsh -Command "Invoke-Pester integration-test/Integration.Tests.ps1" + +# You will be prompted for test application path +# Supply values for the following parameters: +# AppPath: ./path/to/SentryPlayground.sh +``` + +## Test Coverage + +The integration tests cover: + +### Crash Capture Tests +- Application crashes with non-zero exit code +- Event ID is captured from output +- Crash event appears in Sentry +- Exception information is present +- Stack traces are captured +- User context is included +- Integration test tags are set +- Breadcrumbs are collected + +### Message Capture Tests +- Application exits cleanly (exit code 0) +- Event ID is captured from output +- TEST_RESULT indicates success +- Message event appears in Sentry +- Message content is correct +- User context is included +- Integration test tags are set +- Breadcrumbs are collected + +## Output + +Test outputs are saved to `integration-test/output/`: +- `*-crash-stdout.log` - Crash test standard output +- `*-crash-stderr.log` - Crash test standard error +- `*-crash-result.json` - Full crash test result +- `*-message-stdout.log` - Message test standard output +- `*-message-stderr.log` - Message test standard error +- `*-message-result.json` - Full message test result +- `event-*.json` - Events fetched from Sentry API + +## CI Integration + +See `.github/workflows/test-windows.yml` and `.github/workflows/test-linux.yml` for CI usage examples. From a21da84cb272e3b64384dbe88440a0c2e6f9504c Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 11:49:29 +0200 Subject: [PATCH 07/49] Remove platform input --- integration-test/Integration.Tests.ps1 | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 9c1942096..5d0efe894 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -5,15 +5,23 @@ param( [Parameter(Mandatory=$true)] - [string]$AppPath, - - [ValidateSet('Win64', 'Linux')] - [string]$Platform = 'Win64' + [string]$AppPath ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' +# Detect platform based on host OS +$script:Platform = if ($IsWindows -or $env:OS -match 'Windows') { + 'Win64' +} elseif ($IsLinux) { + 'Linux' +} elseif ($IsMacOS) { + 'Mac' +} else { + throw "Unsupported platform. Unable to detect Windows, Linux, or macOS." +} + function script:Convert-HashtableToObject($item) { if ($item -is [System.Collections.IDictionary]) { $obj = [PSCustomObject]@{} @@ -174,12 +182,12 @@ With environment variables: } Write-Host "Test environment ready" -ForegroundColor Green - Write-Host " Platform: $Platform" -ForegroundColor Cyan + Write-Host " Platform: $script:Platform" -ForegroundColor Cyan Write-Host " App: $AppPath" -ForegroundColor Cyan Write-Host " Output: $script:OutputDir" -ForegroundColor Cyan } -Describe "Sentry Unreal Integration Tests ($Platform)" { +Describe "Sentry Unreal Integration Tests ($script:Platform)" { Context "Crash Capture Tests" { BeforeAll { @@ -197,7 +205,7 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { $args = @('-crash-capture', '-NullRHI', '-unattended') # Execute application based on platform - if ($Platform -eq 'Win64') { + if ($script:Platform -eq 'Win64') { $process = Start-Process -FilePath $AppPath -ArgumentList $args ` -Wait -PassThru -NoNewWindow ` -RedirectStandardOutput $stdoutFile ` @@ -209,7 +217,7 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { Error = Get-Content $stderrFile } } else { - # Linux + # Linux or Mac chmod +x $AppPath 2>&1 | Out-Null $output = & $AppPath @args 2>&1 $output | Out-File $stdoutFile @@ -310,7 +318,7 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { $args = @('-message-capture', '-NullRHI', '-unattended') # Execute application based on platform - if ($Platform -eq 'Win64') { + if ($script:Platform -eq 'Win64') { $process = Start-Process -FilePath $AppPath -ArgumentList $args ` -Wait -PassThru -NoNewWindow ` -RedirectStandardOutput $stdoutFile ` @@ -322,7 +330,7 @@ Describe "Sentry Unreal Integration Tests ($Platform)" { Error = Get-Content $stderrFile } } else { - # Linux + # Linux or Mac $output = & $AppPath @args 2>&1 $output | Out-File $stdoutFile From 80eb26becd12a3a098f18c199bc094e312342c07 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 14:27:46 +0200 Subject: [PATCH 08/49] Clean up --- integration-test/Integration.Tests.ps1 | 152 +++++++++++-------------- 1 file changed, 64 insertions(+), 88 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 5d0efe894..58a3bb95d 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -1,27 +1,11 @@ # Integration tests for Sentry Unreal SDK # Requires: # - Pre-built SentryPlayground application -# - Environment variables: SENTRY_UNREAL_TEST_DSN, SENTRY_AUTH_TOKEN - -param( - [Parameter(Mandatory=$true)] - [string]$AppPath -) +# - Environment variables: SENTRY_UNREAL_TEST_DSN, SENTRY_AUTH_TOKEN, SENTRY_UNREAL_SAMPLE_APP_PATH Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' -# Detect platform based on host OS -$script:Platform = if ($IsWindows -or $env:OS -match 'Windows') { - 'Win64' -} elseif ($IsLinux) { - 'Linux' -} elseif ($IsMacOS) { - 'Mac' -} else { - throw "Unsupported platform. Unable to detect Windows, Linux, or macOS." -} - function script:Convert-HashtableToObject($item) { if ($item -is [System.Collections.IDictionary]) { $obj = [PSCustomObject]@{} @@ -135,21 +119,49 @@ function script:Get-SentryUnrealTestEvent { } } +function script:Invoke-SentryUnrealTestApp { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string[]]$Arguments, + + [Parameter(Mandatory)] + [string]$StdoutFile, + + [Parameter(Mandatory)] + [string]$StderrFile + ) + + if ($script:Platform -eq 'Win64') { + $process = Start-Process -FilePath $script:AppPath -ArgumentList $Arguments ` + -Wait -PassThru -NoNewWindow ` + -RedirectStandardOutput $StdoutFile ` + -RedirectStandardError $StderrFile + + return @{ + ExitCode = $process.ExitCode + Output = Get-Content $StdoutFile + Error = Get-Content $StderrFile + } + } else { + # Linux or Mac + chmod +x $script:AppPath 2>&1 | Out-Null + $output = & $script:AppPath @Arguments 2>&1 + $output | Out-File $StdoutFile + + return @{ + ExitCode = $LASTEXITCODE + Output = $output + Error = @() + } + } +} + BeforeAll { - # Check if environment is configured + # Check if configuration file exists $configFile = "$PSScriptRoot/TestConfig.local.ps1" if (-not (Test-Path $configFile)) { - throw @" -Integration test environment not configured. - -Please run: - cd integration-test - cmake -B build -S . - -With environment variables: - SENTRY_UNREAL_TEST_DSN=https://... - SENTRY_AUTH_TOKEN=sntrys_... -"@ + throw "Configuration file '$configFile' not found." } # Load configuration (provides $global:AppRunnerPath) @@ -161,18 +173,23 @@ With environment variables: # Validate environment variables $script:DSN = $env:SENTRY_UNREAL_TEST_DSN $script:AuthToken = $env:SENTRY_AUTH_TOKEN + $script:AppPath = $env:SENTRY_UNREAL_SAMPLE_APP_PATH if (-not $script:DSN -or -not $script:AuthToken) { throw "Environment variables SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN must be set" } + if (-not $script:AppPath) { + throw "Environment variable SENTRY_UNREAL_SAMPLE_APP_PATH must be set" + } + # Connect to Sentry API Write-Host "Connecting to Sentry API..." -ForegroundColor Yellow Connect-SentryApi -DSN $script:DSN -ApiToken $script:AuthToken # Validate app path - if (-not (Test-Path $AppPath)) { - throw "Application not found at: $AppPath" + if (-not (Test-Path $script:AppPath)) { + throw "Application not found at: $script:AppPath" } # Create output directory @@ -181,10 +198,16 @@ With environment variables: New-Item -ItemType Directory -Path $script:OutputDir | Out-Null } - Write-Host "Test environment ready" -ForegroundColor Green - Write-Host " Platform: $script:Platform" -ForegroundColor Cyan - Write-Host " App: $AppPath" -ForegroundColor Cyan - Write-Host " Output: $script:OutputDir" -ForegroundColor Cyan + # Detect platform based on host OS + $script:Platform = if ($IsWindows -or $env:OS -match 'Windows') { + 'Win64' + } elseif ($IsLinux) { + 'Linux' + } elseif ($IsMacOS) { + 'Mac' + } else { + throw "Unsupported platform. Unable to detect Windows, Linux, or macOS." + } } Describe "Sentry Unreal Integration Tests ($script:Platform)" { @@ -201,33 +224,9 @@ Describe "Sentry Unreal Integration Tests ($script:Platform)" { $stdoutFile = "$script:OutputDir/$timestamp-crash-stdout.log" $stderrFile = "$script:OutputDir/$timestamp-crash-stderr.log" - # Build arguments - $args = @('-crash-capture', '-NullRHI', '-unattended') - - # Execute application based on platform - if ($script:Platform -eq 'Win64') { - $process = Start-Process -FilePath $AppPath -ArgumentList $args ` - -Wait -PassThru -NoNewWindow ` - -RedirectStandardOutput $stdoutFile ` - -RedirectStandardError $stderrFile - - $script:CrashResult = @{ - ExitCode = $process.ExitCode - Output = Get-Content $stdoutFile - Error = Get-Content $stderrFile - } - } else { - # Linux or Mac - chmod +x $AppPath 2>&1 | Out-Null - $output = & $AppPath @args 2>&1 - $output | Out-File $stdoutFile - - $script:CrashResult = @{ - ExitCode = $LASTEXITCODE - Output = $output - Error = @() - } - } + # Build arguments and execute application + $appArgs = @('-crash-capture', '-NullRHI', '-unattended') + $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output $script:CrashResult | ConvertTo-Json -Depth 5 | Out-File "$script:OutputDir/$timestamp-crash-result.json" @@ -314,32 +313,9 @@ Describe "Sentry Unreal Integration Tests ($script:Platform)" { $stdoutFile = "$script:OutputDir/$timestamp-message-stdout.log" $stderrFile = "$script:OutputDir/$timestamp-message-stderr.log" - # Build arguments - $args = @('-message-capture', '-NullRHI', '-unattended') - - # Execute application based on platform - if ($script:Platform -eq 'Win64') { - $process = Start-Process -FilePath $AppPath -ArgumentList $args ` - -Wait -PassThru -NoNewWindow ` - -RedirectStandardOutput $stdoutFile ` - -RedirectStandardError $stderrFile - - $script:MessageResult = @{ - ExitCode = $process.ExitCode - Output = Get-Content $stdoutFile - Error = Get-Content $stderrFile - } - } else { - # Linux or Mac - $output = & $AppPath @args 2>&1 - $output | Out-File $stdoutFile - - $script:MessageResult = @{ - ExitCode = $LASTEXITCODE - Output = $output - Error = @() - } - } + # Build arguments and execute application + $appArgs = @('-message-capture', '-NullRHI', '-unattended') + $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output $script:MessageResult | ConvertTo-Json -Depth 5 | Out-File "$script:OutputDir/$timestamp-message-result.json" From c22a6446460ac8da9e98942241f9928c1f167a59 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 14:29:16 +0200 Subject: [PATCH 09/49] Rename --- integration-test/Integration.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 58a3bb95d..39372b423 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -1,7 +1,7 @@ # Integration tests for Sentry Unreal SDK # Requires: # - Pre-built SentryPlayground application -# - Environment variables: SENTRY_UNREAL_TEST_DSN, SENTRY_AUTH_TOKEN, SENTRY_UNREAL_SAMPLE_APP_PATH +# - Environment variables: SENTRY_UNREAL_TEST_DSN, SENTRY_AUTH_TOKEN, SENTRY_UNREAL_TEST_APP_PATH Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' @@ -173,14 +173,14 @@ BeforeAll { # Validate environment variables $script:DSN = $env:SENTRY_UNREAL_TEST_DSN $script:AuthToken = $env:SENTRY_AUTH_TOKEN - $script:AppPath = $env:SENTRY_UNREAL_SAMPLE_APP_PATH + $script:AppPath = $env:SENTRY_UNREAL_TEST_APP_PATH if (-not $script:DSN -or -not $script:AuthToken) { throw "Environment variables SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN must be set" } if (-not $script:AppPath) { - throw "Environment variable SENTRY_UNREAL_SAMPLE_APP_PATH must be set" + throw "Environment variable SENTRY_UNREAL_TEST_APP_PATH must be set" } # Connect to Sentry API From f50262b46a6693e818adc2246482d50a83b3e0d1 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 16:05:36 +0200 Subject: [PATCH 10/49] Clean up --- integration-test/Integration.Tests.ps1 | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 39372b423..003374e60 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -132,7 +132,7 @@ function script:Invoke-SentryUnrealTestApp { [string]$StderrFile ) - if ($script:Platform -eq 'Win64') { + if ($IsWindows -or $env:OS -eq 'Windows_NT') { $process = Start-Process -FilePath $script:AppPath -ArgumentList $Arguments ` -Wait -PassThru -NoNewWindow ` -RedirectStandardOutput $StdoutFile ` @@ -175,8 +175,12 @@ BeforeAll { $script:AuthToken = $env:SENTRY_AUTH_TOKEN $script:AppPath = $env:SENTRY_UNREAL_TEST_APP_PATH - if (-not $script:DSN -or -not $script:AuthToken) { - throw "Environment variables SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN must be set" + if (-not $script:DSN) { + throw "Environment variable SENTRY_UNREAL_TEST_DSN must be set" + } + + if (-not $script:AuthToken) { + throw "Environment variable SENTRY_AUTH_TOKEN must be set" } if (-not $script:AppPath) { @@ -197,20 +201,9 @@ BeforeAll { if (-not (Test-Path $script:OutputDir)) { New-Item -ItemType Directory -Path $script:OutputDir | Out-Null } - - # Detect platform based on host OS - $script:Platform = if ($IsWindows -or $env:OS -match 'Windows') { - 'Win64' - } elseif ($IsLinux) { - 'Linux' - } elseif ($IsMacOS) { - 'Mac' - } else { - throw "Unsupported platform. Unable to detect Windows, Linux, or macOS." - } } -Describe "Sentry Unreal Integration Tests ($script:Platform)" { +Describe "Sentry Unreal Integration Tests" { Context "Crash Capture Tests" { BeforeAll { From 5c72f0eccd73d0e0363c399b2574ed9a1da24c1b Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 16:05:47 +0200 Subject: [PATCH 11/49] Add integration tests run to CI --- .github/workflows/test-linux.yml | 15 ++++++++++++++- .github/workflows/test-windows.yml | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index f0ccb94b2..d6f524375 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -168,4 +168,17 @@ jobs: with: name: UE ${{ inputs.unreal-version }} sample build (Linux) path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/ - retention-days: 1 + retention-days: 1 + + - name: Run integration tests + id: run-integration-tests + if: ${{ success() && steps.run-tests.outcome == 'success' }} + env: + SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/SentryPlayground.sh + run: | + cd checkout/integration-test + mkdir build + cmake -B build -S . + pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1" diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 83d5f978a..f8deee3b5 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -106,4 +106,17 @@ jobs: name: UE ${{ inputs.unreal-version }} sample build (Windows) path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/ retention-days: 1 - + + - name: Run integration tests + id: run-integration-tests + if: ${{ success() && steps.run-tests.outcome == 'success' }} + env: + SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/SentryPlayground.exe + run: | + cd checkout/integration-test + mkdir build + cmake -B build -S . + pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1" + From cf9867e8e152bfebf34ae788d9c850cf29b5d31a Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 16:50:12 +0200 Subject: [PATCH 12/49] Install Pester on Linux --- .github/workflows/test-linux.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index d6f524375..6065e372e 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -168,7 +168,12 @@ jobs: with: name: UE ${{ inputs.unreal-version }} sample build (Linux) path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/ - retention-days: 1 + retention-days: 1 + + - name: Install Pester + shell: pwsh + run: | + Install-Module -Name Pester -Force -SkipPublisherCheck - name: Run integration tests id: run-integration-tests From 33e8c09f93582ef7d112faf8d4890187ca414fc4 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 17:00:08 +0200 Subject: [PATCH 13/49] Add CI flag --- .github/workflows/test-linux.yml | 2 +- .github/workflows/test-windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 6065e372e..1b09b56e3 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -186,4 +186,4 @@ jobs: cd checkout/integration-test mkdir build cmake -B build -S . - pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1" + pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1 -CI" diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index f8deee3b5..3d69ade1d 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -118,5 +118,5 @@ jobs: cd checkout/integration-test mkdir build cmake -B build -S . - pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1" + pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1 -CI" From 1d9c63bcd42681f8c370bdddd9873a7beea3b272 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 17:33:15 +0200 Subject: [PATCH 14/49] Try fix auth --- .github/workflows/test-linux.yml | 2 +- .github/workflows/test-windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 1b09b56e3..2afafae38 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -180,7 +180,7 @@ jobs: if: ${{ success() && steps.run-tests.outcome == 'success' }} env: SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/SentryPlayground.sh run: | cd checkout/integration-test diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 3d69ade1d..328d79ea5 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -112,7 +112,7 @@ jobs: if: ${{ success() && steps.run-tests.outcome == 'success' }} env: SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/SentryPlayground.exe run: | cd checkout/integration-test From 277f3218e860e33aac6ef2c0e9d1afb3ec0b9b23 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Mon, 27 Oct 2025 18:08:03 +0200 Subject: [PATCH 15/49] Serialize --- integration-test/Integration.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 003374e60..60de3119b 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -222,7 +222,7 @@ Describe "Sentry Unreal Integration Tests" { $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output - $script:CrashResult | ConvertTo-Json -Depth 5 | Out-File "$script:OutputDir/$timestamp-crash-result.json" + $script:CrashResult | ConvertTo-Json -Depth 10 | Out-File "$script:OutputDir/$timestamp-crash-result.json" Write-Host "Crash test executed. Exit code: $($script:CrashResult.ExitCode)" -ForegroundColor Cyan @@ -311,7 +311,7 @@ Describe "Sentry Unreal Integration Tests" { $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output - $script:MessageResult | ConvertTo-Json -Depth 5 | Out-File "$script:OutputDir/$timestamp-message-result.json" + $script:MessageResult | ConvertTo-Json -Depth 10 | Out-File "$script:OutputDir/$timestamp-message-result.json" Write-Host "Message test executed. Exit code: $($script:MessageResult.ExitCode)" -ForegroundColor Cyan From 3df874c0ab5a0b080acdf1bd1f4c7471cb5b7296 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 08:35:10 +0200 Subject: [PATCH 16/49] Test --- .github/workflows/test-linux.yml | 3 ++- .github/workflows/test-windows.yml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 2afafae38..6a3ea2d31 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -178,6 +178,7 @@ jobs: - name: Run integration tests id: run-integration-tests if: ${{ success() && steps.run-tests.outcome == 'success' }} + shell: pwsh env: SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} @@ -186,4 +187,4 @@ jobs: cd checkout/integration-test mkdir build cmake -B build -S . - pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1 -CI" + Invoke-Pester Integration.Tests.ps1 -CI diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 328d79ea5..61ab504e6 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -115,8 +115,8 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/SentryPlayground.exe run: | - cd checkout/integration-test + cd "$env:WORKSPACE_PATH/checkout/integration-test" mkdir build cmake -B build -S . - pwsh -Command "Invoke-Pester -Path ./Integration.Tests.ps1 -CI" + Invoke-Pester Integration.Tests.ps1 -CI" From 331a27e161c355b30cab19d89d4006918020ded0 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 09:36:56 +0200 Subject: [PATCH 17/49] Test --- integration-test/Integration.Tests.ps1 | 77 ++++++++++++++++++++------ 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 60de3119b..a63ec2eea 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -129,31 +129,74 @@ function script:Invoke-SentryUnrealTestApp { [string]$StdoutFile, [Parameter(Mandatory)] - [string]$StderrFile + [string]$StderrFile, + + [Parameter()] + [int]$TimeoutSeconds = 300 ) - if ($IsWindows -or $env:OS -eq 'Windows_NT') { + # Ensure executable permission on Unix-based systems + if (-not ($IsWindows -or $env:OS -eq 'Windows_NT')) { + chmod +x $script:AppPath 2>&1 | Out-Null + } + + # Use Start-Process for all platforms to ensure consistent behavior + # This properly captures output and exit code even if the process hangs or crashes + $exitCode = -1 + $timedOut = $false + + try { + Write-Host "Starting test app with timeout of $TimeoutSeconds seconds..." -ForegroundColor Yellow + $process = Start-Process -FilePath $script:AppPath -ArgumentList $Arguments ` - -Wait -PassThru -NoNewWindow ` + -PassThru -NoNewWindow ` -RedirectStandardOutput $StdoutFile ` -RedirectStandardError $StderrFile - return @{ - ExitCode = $process.ExitCode - Output = Get-Content $StdoutFile - Error = Get-Content $StderrFile + # Wait for process with timeout + $processId = $process.Id + Write-Host "Process started with PID: $processId" -ForegroundColor Cyan + + if ($process.WaitForExit($TimeoutSeconds * 1000)) { + $exitCode = $process.ExitCode + Write-Host "Process completed with exit code: $exitCode" -ForegroundColor Cyan + } else { + $timedOut = $true + Write-Host "Process timed out after $TimeoutSeconds seconds. Killing process..." -ForegroundColor Red + $process.Kill($true) # Kill process tree + $exitCode = -1 } - } else { - # Linux or Mac - chmod +x $script:AppPath 2>&1 | Out-Null - $output = & $script:AppPath @Arguments 2>&1 - $output | Out-File $StdoutFile + } catch { + Write-Host "Process execution failed: $_" -ForegroundColor Red + # If Start-Process fails, try to read any output that was captured + $exitCode = -1 + } - return @{ - ExitCode = $LASTEXITCODE - Output = $output - Error = @() - } + # Read output from files to ensure we get everything that was written + $stdout = @() + $stderr = @() + + if (Test-Path $StdoutFile) { + $stdout = Get-Content $StdoutFile -ErrorAction SilentlyContinue + } + + if (Test-Path $StderrFile) { + $stderr = Get-Content $StderrFile -ErrorAction SilentlyContinue + } + + if ($timedOut) { + Write-Host "Test app output before timeout:" -ForegroundColor Yellow + Write-Host "STDOUT (last 50 lines):" -ForegroundColor Yellow + $stdout | Select-Object -Last 50 | ForEach-Object { Write-Host $_ } + Write-Host "STDERR (last 50 lines):" -ForegroundColor Yellow + $stderr | Select-Object -Last 50 | ForEach-Object { Write-Host $_ } + } + + return @{ + ExitCode = $exitCode + Output = $stdout + Error = $stderr + TimedOut = $timedOut } } From f276785a5f4036694830e6c2fc88e743a578f4bd Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 10:02:51 +0200 Subject: [PATCH 18/49] stdout --- integration-test/Integration.Tests.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index a63ec2eea..1215c375a 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -261,7 +261,8 @@ Describe "Sentry Unreal Integration Tests" { $stderrFile = "$script:OutputDir/$timestamp-crash-stderr.log" # Build arguments and execute application - $appArgs = @('-crash-capture', '-NullRHI', '-unattended') + # -stdout ensures logs are written to stdout on Linux/Unix systems + $appArgs = @('-crash-capture', '-NullRHI', '-unattended', '-stdout') $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output @@ -350,7 +351,8 @@ Describe "Sentry Unreal Integration Tests" { $stderrFile = "$script:OutputDir/$timestamp-message-stderr.log" # Build arguments and execute application - $appArgs = @('-message-capture', '-NullRHI', '-unattended') + # -stdout ensures logs are written to stdout on Linux/Unix systems + $appArgs = @('-message-capture', '-NullRHI', '-unattended', '-stdout') $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output From 25d93ce506e8ebf10c892230a5d7b8b08f025933 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 10:22:29 +0200 Subject: [PATCH 19/49] Force flush logs --- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 08f4d8400..afb7613fb 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -82,6 +82,9 @@ void USentryPlaygroundGameInstance::RunCrashTest() UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *EventId); + // Flush logs to ensure output is captured before crash + GLog->Flush(); + SentrySubsystem->SetTag(TEXT("test.crash_id"), EventId); USentryPlaygroundUtils::Terminate(ESentryAppTerminationType::NullPointer); @@ -95,6 +98,9 @@ void USentryPlaygroundGameInstance::RunMessageTest() UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); + // Flush logs to ensure output is captured before exit + GLog->Flush(); + CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete")); } @@ -118,6 +124,9 @@ void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestNa UE_LOG(LogSentrySample, Display, TEXT("TEST_RESULT: {\"test\":\"%s\",\"success\":%s,\"message\":\"%s\"}\n"), *TestName, Result ? TEXT("true") : TEXT("false"), *Message); + // Flush logs to ensure output is captured before exit + GLog->Flush(); + // Close app after test is completed FGenericPlatformMisc::RequestExit(false); } From 0e2f5e1dad0468c6a1aca3b6b43cc8deb6777500 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 10:22:40 +0200 Subject: [PATCH 20/49] Clean up --- integration-test/Integration.Tests.ps1 | 28 +------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 1215c375a..af52a7f12 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -135,40 +135,23 @@ function script:Invoke-SentryUnrealTestApp { [int]$TimeoutSeconds = 300 ) - # Ensure executable permission on Unix-based systems - if (-not ($IsWindows -or $env:OS -eq 'Windows_NT')) { - chmod +x $script:AppPath 2>&1 | Out-Null - } - - # Use Start-Process for all platforms to ensure consistent behavior - # This properly captures output and exit code even if the process hangs or crashes $exitCode = -1 - $timedOut = $false try { - Write-Host "Starting test app with timeout of $TimeoutSeconds seconds..." -ForegroundColor Yellow - $process = Start-Process -FilePath $script:AppPath -ArgumentList $Arguments ` -PassThru -NoNewWindow ` -RedirectStandardOutput $StdoutFile ` -RedirectStandardError $StderrFile - # Wait for process with timeout - $processId = $process.Id - Write-Host "Process started with PID: $processId" -ForegroundColor Cyan - if ($process.WaitForExit($TimeoutSeconds * 1000)) { $exitCode = $process.ExitCode - Write-Host "Process completed with exit code: $exitCode" -ForegroundColor Cyan } else { - $timedOut = $true Write-Host "Process timed out after $TimeoutSeconds seconds. Killing process..." -ForegroundColor Red - $process.Kill($true) # Kill process tree + $process.Kill($true) $exitCode = -1 } } catch { Write-Host "Process execution failed: $_" -ForegroundColor Red - # If Start-Process fails, try to read any output that was captured $exitCode = -1 } @@ -184,19 +167,10 @@ function script:Invoke-SentryUnrealTestApp { $stderr = Get-Content $StderrFile -ErrorAction SilentlyContinue } - if ($timedOut) { - Write-Host "Test app output before timeout:" -ForegroundColor Yellow - Write-Host "STDOUT (last 50 lines):" -ForegroundColor Yellow - $stdout | Select-Object -Last 50 | ForEach-Object { Write-Host $_ } - Write-Host "STDERR (last 50 lines):" -ForegroundColor Yellow - $stderr | Select-Object -Last 50 | ForEach-Object { Write-Host $_ } - } - return @{ ExitCode = $exitCode Output = $stdout Error = $stderr - TimedOut = $timedOut } } From c02798ffddd30d256afc1ad1b9196a69c6ae8789 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 11:12:15 +0200 Subject: [PATCH 21/49] Add integration tests output upload --- .github/workflows/test-linux.yml | 7 +++++++ .github/workflows/test-windows.yml | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 6a3ea2d31..b6b0fdf20 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -188,3 +188,10 @@ jobs: mkdir build cmake -B build -S . Invoke-Pester Integration.Tests.ps1 -CI + + - name: Upload integration test output + if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} integration test output (Linux) + path: checkout/integration-test/output/ diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 61ab504e6..1a14f454f 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -118,5 +118,12 @@ jobs: cd "$env:WORKSPACE_PATH/checkout/integration-test" mkdir build cmake -B build -S . - Invoke-Pester Integration.Tests.ps1 -CI" + Invoke-Pester Integration.Tests.ps1 -CI + + - name: Upload integration test output + if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} integration test output (Windows) + path: checkout/integration-test/output/ From bf6a1218bd9d8eb13c54e4a9ec0f89d2a2bfea9a Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 11:20:53 +0200 Subject: [PATCH 22/49] Extract integration tests to separate jobs --- .github/workflows/ci.yml | 25 ++++++++++ .github/workflows/integration-test-linux.yml | 47 +++++++++++++++++++ .../workflows/integration-test-windows.yml | 41 ++++++++++++++++ .github/workflows/test-linux.yml | 26 ---------- .github/workflows/test-windows.yml | 20 -------- 5 files changed, 113 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/integration-test-linux.yml create mode 100644 .github/workflows/integration-test-windows.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec151e2f9..20985bc05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,3 +161,28 @@ jobs: uses: ./.github/workflows/test-windows.yml with: unreal-version: ${{ matrix.unreal }} + + integration-test-linux: + needs: [test-linux] + name: Linux UE ${{ matrix.unreal }} + secrets: inherit + strategy: + fail-fast: false + matrix: + unreal: ['4.27', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6'] + uses: ./.github/workflows/integration-test-linux.yml + with: + unreal-version: ${{ matrix.unreal }} + + integration-test-windows: + needs: [test-windows] + name: Windows UE ${{ matrix.unreal }} + secrets: inherit + strategy: + fail-fast: false + matrix: + # Integration tests only for UE 5.2 and newer where CRC can be disabled + unreal: ['5.2', '5.3', '5.4', '5.5', '5.6'] + uses: ./.github/workflows/integration-test-windows.yml + with: + unreal-version: ${{ matrix.unreal }} diff --git a/.github/workflows/integration-test-linux.yml b/.github/workflows/integration-test-linux.yml new file mode 100644 index 000000000..69ab626aa --- /dev/null +++ b/.github/workflows/integration-test-linux.yml @@ -0,0 +1,47 @@ +on: + workflow_call: + inputs: + unreal-version: + required: true + type: string + +jobs: + integration-test: + name: Integration Test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Download sample build + uses: actions/download-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} sample build (Linux) + path: sample-build + + - name: Install Pester + shell: pwsh + run: | + Install-Module -Name Pester -Force -SkipPublisherCheck + + - name: Run integration tests + id: run-integration-tests + shell: pwsh + env: + SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} + SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/sample-build/SentryPlayground.sh + run: | + cd integration-test + mkdir build + cmake -B build -S . + Invoke-Pester Integration.Tests.ps1 -CI + + - name: Upload integration test output + if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} integration test output (Linux) + path: integration-test/output/ diff --git a/.github/workflows/integration-test-windows.yml b/.github/workflows/integration-test-windows.yml new file mode 100644 index 000000000..1a0dbcc13 --- /dev/null +++ b/.github/workflows/integration-test-windows.yml @@ -0,0 +1,41 @@ +on: + workflow_call: + inputs: + unreal-version: + required: true + type: string + +jobs: + integration-test: + name: Integration Test + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Download sample build + uses: actions/download-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} sample build (Windows) + path: sample-build + + - name: Run integration tests + id: run-integration-tests + env: + SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} + SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/sample-build/SentryPlayground.exe + run: | + cd integration-test + mkdir build + cmake -B build -S . + Invoke-Pester Integration.Tests.ps1 -CI + + - name: Upload integration test output + if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} integration test output (Windows) + path: integration-test/output/ diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index b6b0fdf20..f0ccb94b2 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -169,29 +169,3 @@ jobs: name: UE ${{ inputs.unreal-version }} sample build (Linux) path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/ retention-days: 1 - - - name: Install Pester - shell: pwsh - run: | - Install-Module -Name Pester -Force -SkipPublisherCheck - - - name: Run integration tests - id: run-integration-tests - if: ${{ success() && steps.run-tests.outcome == 'success' }} - shell: pwsh - env: - SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} - SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/SentryPlayground.sh - run: | - cd checkout/integration-test - mkdir build - cmake -B build -S . - Invoke-Pester Integration.Tests.ps1 -CI - - - name: Upload integration test output - if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }} - uses: actions/upload-artifact@v4 - with: - name: UE ${{ inputs.unreal-version }} integration test output (Linux) - path: checkout/integration-test/output/ diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 1a14f454f..82ad28210 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -107,23 +107,3 @@ jobs: path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/ retention-days: 1 - - name: Run integration tests - id: run-integration-tests - if: ${{ success() && steps.run-tests.outcome == 'success' }} - env: - SENTRY_UNREAL_TEST_DSN: ${{ secrets.SENTRY_UNREAL_TEST_DSN }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_API_TOKEN }} - SENTRY_UNREAL_TEST_APP_PATH: ${{ github.workspace }}/checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/SentryPlayground.exe - run: | - cd "$env:WORKSPACE_PATH/checkout/integration-test" - mkdir build - cmake -B build -S . - Invoke-Pester Integration.Tests.ps1 -CI - - - name: Upload integration test output - if: ${{ always() && steps.run-integration-tests.outcome == 'failure' }} - uses: actions/upload-artifact@v4 - with: - name: UE ${{ inputs.unreal-version }} integration test output (Windows) - path: checkout/integration-test/output/ - From 8ce5cc89ed0d6226b95b11a0dc6cefe6d8dec5d3 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 11:24:21 +0200 Subject: [PATCH 23/49] Fix eof --- .github/workflows/test-windows.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 82ad28210..3c1defdeb 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -106,4 +106,3 @@ jobs: name: UE ${{ inputs.unreal-version }} sample build (Windows) path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/ retention-days: 1 - From 57d93eb1d8bff90223b2323a895f7baac13802e5 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 13:10:42 +0200 Subject: [PATCH 24/49] Fix permission --- .github/workflows/integration-test-linux.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/integration-test-linux.yml b/.github/workflows/integration-test-linux.yml index 69ab626aa..772f9eee9 100644 --- a/.github/workflows/integration-test-linux.yml +++ b/.github/workflows/integration-test-linux.yml @@ -21,6 +21,9 @@ jobs: name: UE ${{ inputs.unreal-version }} sample build (Linux) path: sample-build + - name: Set execute permissions + run: chmod +x ${{ github.workspace }}/sample-build/SentryPlayground.sh + - name: Install Pester shell: pwsh run: | From e5a42af551bf85dcc39153933b65b5fc1644b704 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 14:33:14 +0200 Subject: [PATCH 25/49] Fix test app exit for non-fatal events --- sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index afb7613fb..46e6f93de 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -128,7 +128,7 @@ void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestNa GLog->Flush(); // Close app after test is completed - FGenericPlatformMisc::RequestExit(false); + FGenericPlatformMisc::RequestExitWithStatus(true, 0); } FString USentryPlaygroundGameInstance::FormatEventIdWithHyphens(const FString& EventId) From 56f7afe56482e28bf75d8ec5c3250549c8462d75 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 14:36:32 +0200 Subject: [PATCH 26/49] Fix exec permission for crashpad --- .github/workflows/integration-test-linux.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-test-linux.yml b/.github/workflows/integration-test-linux.yml index 772f9eee9..1901af262 100644 --- a/.github/workflows/integration-test-linux.yml +++ b/.github/workflows/integration-test-linux.yml @@ -22,7 +22,9 @@ jobs: path: sample-build - name: Set execute permissions - run: chmod +x ${{ github.workspace }}/sample-build/SentryPlayground.sh + run: | + chmod +x ${{ github.workspace }}/sample-build/SentryPlayground.sh + chmod +x ${{ github.workspace }}/sample-build/SentryPlayground/Plugins/sentry/Binaries/Linux/crashpad_handler - name: Install Pester shell: pwsh From a81607890b07f3c9b6f9b674ba1b342a94033a18 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 17:28:50 +0200 Subject: [PATCH 27/49] Upload game log --- .github/workflows/integration-test-linux.yml | 4 +++- .github/workflows/integration-test-windows.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-test-linux.yml b/.github/workflows/integration-test-linux.yml index 1901af262..66dfc856a 100644 --- a/.github/workflows/integration-test-linux.yml +++ b/.github/workflows/integration-test-linux.yml @@ -49,4 +49,6 @@ jobs: uses: actions/upload-artifact@v4 with: name: UE ${{ inputs.unreal-version }} integration test output (Linux) - path: integration-test/output/ + path: | + integration-test/output/ + sample-build/SentryPlayground/Saved/Logs/ diff --git a/.github/workflows/integration-test-windows.yml b/.github/workflows/integration-test-windows.yml index 1a0dbcc13..03cddd8e0 100644 --- a/.github/workflows/integration-test-windows.yml +++ b/.github/workflows/integration-test-windows.yml @@ -38,4 +38,6 @@ jobs: uses: actions/upload-artifact@v4 with: name: UE ${{ inputs.unreal-version }} integration test output (Windows) - path: integration-test/output/ + path: | + integration-test/output/ + sample-build/SentryPlayground/Saved/Logs/ From 665f3000ca40d25813747f1badb205d711f7dc63 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 17:29:32 +0200 Subject: [PATCH 28/49] Update exit --- .../Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 46e6f93de..d3c1bd117 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -128,7 +128,11 @@ void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestNa GLog->Flush(); // Close app after test is completed +#if PLATFORM_WINDOW FGenericPlatformMisc::RequestExitWithStatus(true, 0); +#else + FGenericPlatformMisc::RequestExit(false); +#endif } FString USentryPlaygroundGameInstance::FormatEventIdWithHyphens(const FString& EventId) From 1b63a655c518682e410f2d3fe66bf6811f4fd3ee Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 17:52:57 +0200 Subject: [PATCH 29/49] Fix --- .../Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index d3c1bd117..45b4ce3a2 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -8,6 +8,7 @@ #include "SentryPlaygroundUtils.h" #include "SentryUser.h" +#include "HAL/Platform.h" #include "Misc/CommandLine.h" #include "Engine/Engine.h" @@ -128,7 +129,7 @@ void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestNa GLog->Flush(); // Close app after test is completed -#if PLATFORM_WINDOW +#if PLATFORM_WINDOWS FGenericPlatformMisc::RequestExitWithStatus(true, 0); #else FGenericPlatformMisc::RequestExit(false); From 44a3cda543367d17db7dff056a7834a0a6895f49 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 18:03:17 +0200 Subject: [PATCH 30/49] Try fix duplicated logs --- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 45b4ce3a2..fbe4cb1fe 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -8,7 +8,9 @@ #include "SentryPlaygroundUtils.h" #include "SentryUser.h" +#include "CoreGlobals.h" #include "HAL/Platform.h" +#include "Misc/EngineVersionComparison.h" #include "Misc/CommandLine.h" #include "Engine/Engine.h" @@ -16,6 +18,14 @@ void USentryPlaygroundGameInstance::Init() { Super::Init(); + // Workaround for duplicated log messages in UE 4.27 on Linux +#if PLATFORM_LINUX && UE_VERSION_OLDER_THAN(5, 0, 0) + if (GLogConsole) + { + GLog->RemoveOutputDevice(GLogConsole); + } +#endif + const TCHAR* CommandLine = FCommandLine::Get(); // Check for expected test parameters to decide between running integration tests From 227e502d6d8ed2dce2bc753e80dbabc537354655 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 19:12:56 +0200 Subject: [PATCH 31/49] Fix --- sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index fbe4cb1fe..c39c32349 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -22,7 +22,7 @@ void USentryPlaygroundGameInstance::Init() #if PLATFORM_LINUX && UE_VERSION_OLDER_THAN(5, 0, 0) if (GLogConsole) { - GLog->RemoveOutputDevice(GLogConsole); + GLog->RemoveOutputDevice(&GLogConsole); } #endif From a27236397a853ec1d27775766b113870f82d040b Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 19:18:13 +0200 Subject: [PATCH 32/49] Test --- sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index c39c32349..aabd63116 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -142,7 +142,7 @@ void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestNa #if PLATFORM_WINDOWS FGenericPlatformMisc::RequestExitWithStatus(true, 0); #else - FGenericPlatformMisc::RequestExit(false); + FGenericPlatformMisc::RequestExit(true); #endif } From 2ebe49412035bbb2e539edefb3853490f06d5f6e Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 19:34:40 +0200 Subject: [PATCH 33/49] Test --- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index aabd63116..6c736ae1e 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -139,11 +139,7 @@ void USentryPlaygroundGameInstance::CompleteTestWithResult(const FString& TestNa GLog->Flush(); // Close app after test is completed -#if PLATFORM_WINDOWS - FGenericPlatformMisc::RequestExitWithStatus(true, 0); -#else - FGenericPlatformMisc::RequestExit(true); -#endif + FPlatformMisc::RequestExitWithStatus(true, 0); } FString USentryPlaygroundGameInstance::FormatEventIdWithHyphens(const FString& EventId) From 340db0d3319a12a74d710a4d5580e25969700209 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 19:36:56 +0200 Subject: [PATCH 34/49] Log duplication --- .../SentryPlaygroundGameInstance.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 6c736ae1e..35a03a4a7 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -18,14 +18,6 @@ void USentryPlaygroundGameInstance::Init() { Super::Init(); - // Workaround for duplicated log messages in UE 4.27 on Linux -#if PLATFORM_LINUX && UE_VERSION_OLDER_THAN(5, 0, 0) - if (GLogConsole) - { - GLog->RemoveOutputDevice(&GLogConsole); - } -#endif - const TCHAR* CommandLine = FCommandLine::Get(); // Check for expected test parameters to decide between running integration tests @@ -107,7 +99,12 @@ void USentryPlaygroundGameInstance::RunMessageTest() FString EventId = SentrySubsystem->CaptureMessage(TEXT("Integration test message")); + // Workaround for duplicated log messages in UE 4.27 on Linux +#if PLATFORM_LINUX && UE_VERSION_OLDER_THAN(5, 0, 0) + UE_LOG(LogSentrySample, Log, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); +#else UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); +#endif // Flush logs to ensure output is captured before exit GLog->Flush(); From 70782e71b3aa03c3709df4c4944bb1f9175ab3e3 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 21:29:17 +0200 Subject: [PATCH 35/49] Clean up --- .../Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 35a03a4a7..317829da2 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -106,9 +106,6 @@ void USentryPlaygroundGameInstance::RunMessageTest() UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); #endif - // Flush logs to ensure output is captured before exit - GLog->Flush(); - CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete")); } From 8ef9cf15b1415ec36a35dc315205291381e5c358 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 21:29:29 +0200 Subject: [PATCH 36/49] Try wait --- sample/Config/DefaultEngine.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/sample/Config/DefaultEngine.ini b/sample/Config/DefaultEngine.ini index 66348e797..1daa35eff 100644 --- a/sample/Config/DefaultEngine.ini +++ b/sample/Config/DefaultEngine.ini @@ -230,6 +230,7 @@ bGeneratedSYMBundle=True [/Script/Sentry.SentrySettings] CrashReporterUrl="https://o447951.ingest.sentry.io/api/6253052/unreal/93c7a68867db43539980de54f09b139a/" Dsn="https://93c7a68867db43539980de54f09b139a@o447951.ingest.sentry.io/6253052" +CrashpadWaitForUpload=True [/Script/MacTargetPlatform.XcodeProjectSettings] BundleIdentifier=io.sentry.unreal.sample From e11404719a52680c0a763f657b7e59c205aebcbf Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 28 Oct 2025 21:30:40 +0200 Subject: [PATCH 37/49] Close --- sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 317829da2..5dbfc30a7 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -106,6 +106,8 @@ void USentryPlaygroundGameInstance::RunMessageTest() UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); #endif + SentrySubsystem->Close(); + CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete")); } From 4b36e2d0f45f5fd463ca3bbd7c2a39d34b1bdf8f Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 29 Oct 2025 08:24:05 +0200 Subject: [PATCH 38/49] Revert crashpad wait --- sample/Config/DefaultEngine.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/sample/Config/DefaultEngine.ini b/sample/Config/DefaultEngine.ini index 1daa35eff..66348e797 100644 --- a/sample/Config/DefaultEngine.ini +++ b/sample/Config/DefaultEngine.ini @@ -230,7 +230,6 @@ bGeneratedSYMBundle=True [/Script/Sentry.SentrySettings] CrashReporterUrl="https://o447951.ingest.sentry.io/api/6253052/unreal/93c7a68867db43539980de54f09b139a/" Dsn="https://93c7a68867db43539980de54f09b139a@o447951.ingest.sentry.io/6253052" -CrashpadWaitForUpload=True [/Script/MacTargetPlatform.XcodeProjectSettings] BundleIdentifier=io.sentry.unreal.sample From aeba36a09e92bd2e8b0c98477ff638490f79f49b Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 29 Oct 2025 08:38:02 +0200 Subject: [PATCH 39/49] nosplash --- integration-test/Integration.Tests.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index af52a7f12..bf1e4a8e4 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -236,7 +236,8 @@ Describe "Sentry Unreal Integration Tests" { # Build arguments and execute application # -stdout ensures logs are written to stdout on Linux/Unix systems - $appArgs = @('-crash-capture', '-NullRHI', '-unattended', '-stdout') + # -nosplash prevents splash screen and dialogs + $appArgs = @('-crash-capture', '-NullRHI', '-unattended', '-stdout', '-nosplash') $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output @@ -326,7 +327,8 @@ Describe "Sentry Unreal Integration Tests" { # Build arguments and execute application # -stdout ensures logs are written to stdout on Linux/Unix systems - $appArgs = @('-message-capture', '-NullRHI', '-unattended', '-stdout') + # -nosplash prevents splash screen and dialogs + $appArgs = @('-message-capture', '-NullRHI', '-unattended', '-stdout', '-nosplash') $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile # Save full output From e4ba6b2382982d8ee6c00a6ff8eba19d8ab87217 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 29 Oct 2025 08:41:46 +0200 Subject: [PATCH 40/49] Comment --- sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 5dbfc30a7..989b52943 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -106,6 +106,7 @@ void USentryPlaygroundGameInstance::RunMessageTest() UE_LOG(LogSentrySample, Display, TEXT("EVENT_CAPTURED: %s\n"), *FormatEventIdWithHyphens(EventId)); #endif + // Ensure events were flushed SentrySubsystem->Close(); CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete")); From abe5c2fa15924af819b169aed4ac74151d5f760a Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 29 Oct 2025 11:33:46 +0200 Subject: [PATCH 41/49] Install DirectX --- .github/workflows/integration-test-windows.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-test-windows.yml b/.github/workflows/integration-test-windows.yml index 03cddd8e0..71a72ff71 100644 --- a/.github/workflows/integration-test-windows.yml +++ b/.github/workflows/integration-test-windows.yml @@ -8,13 +8,20 @@ on: jobs: integration-test: name: Integration Test - runs-on: windows-latest + runs-on: windows-2022 steps: - uses: actions/checkout@v4 with: submodules: recursive + # UE 5.2-5.3 require older DirectX runtime to run pre-built test app + - name: Install DirectX June 2010 Runtime + run: | + Invoke-WebRequest -Uri "https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe" -OutFile "$env:TEMP\directx_redist.exe" + Start-Process -FilePath "$env:TEMP\directx_redist.exe" -ArgumentList "/Q","/T:$env:TEMP\DirectX" -Wait + Start-Process -FilePath "$env:TEMP\DirectX\DXSETUP.exe" -ArgumentList "/silent" -Wait + - name: Download sample build uses: actions/download-artifact@v4 with: From b64dc16ac40ca2de71f1ac97e775564d0bed728e Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 29 Oct 2025 14:37:06 +0200 Subject: [PATCH 42/49] Update readme --- integration-test/README.md | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/integration-test/README.md b/integration-test/README.md index e54f3eb2d..1d68f51a5 100644 --- a/integration-test/README.md +++ b/integration-test/README.md @@ -11,6 +11,7 @@ This directory contains integration tests for the Sentry Unreal SDK using Pester - **Environment variables**: - `SENTRY_UNREAL_TEST_DSN` - Sentry test project DSN - `SENTRY_AUTH_TOKEN` - Sentry API authentication token + - `SENTRY_UNREAL_TEST_APP_PATH` - Path to the SentryPlayground executable ## Setup @@ -33,10 +34,12 @@ This will: # Windows PowerShell $env:SENTRY_UNREAL_TEST_DSN = "https://key@org.ingest.sentry.io/project" $env:SENTRY_AUTH_TOKEN = "sntrys_your_token_here" +$env:SENTRY_UNREAL_TEST_APP_PATH = "path/to/SentryPlayground.exe" # Linux/macOS export SENTRY_UNREAL_TEST_DSN="https://key@org.ingest.sentry.io/project" export SENTRY_AUTH_TOKEN="sntrys_your_token_here" +export SENTRY_UNREAL_TEST_APP_PATH="./path/to/SentryPlayground.sh" ``` ### 2. Get SentryPlayground Application @@ -59,31 +62,27 @@ Follow the standard Unreal Engine build process for the [sample](./sample/) proj ### Windows ```powershell -# Ensure environment variables are set +# Set environment variables $env:SENTRY_UNREAL_TEST_DSN = "https://..." $env:SENTRY_AUTH_TOKEN = "sntrys_..." +$env:SENTRY_UNREAL_TEST_APP_PATH = "path/to/SentryPlayground.exe" # Run tests -Invoke-Pester integration-test/Integration.Tests.ps1 - -# You will be prompted for test application path -# Supply values for the following parameters: -# AppPath: path/to/SentryPlayground.exe +cd integration-test +Invoke-Pester Integration.Tests.ps1 ``` ### Linux ```bash -# Ensure environment variables are set +# Set environment variables export SENTRY_UNREAL_TEST_DSN="https://..." export SENTRY_AUTH_TOKEN="sntrys_..." +export SENTRY_UNREAL_TEST_APP_PATH="./path/to/SentryPlayground.sh" # Run tests -pwsh -Command "Invoke-Pester integration-test/Integration.Tests.ps1" - -# You will be prompted for test application path -# Supply values for the following parameters: -# AppPath: ./path/to/SentryPlayground.sh +cd integration-test +pwsh -Command "Invoke-Pester Integration.Tests.ps1" ``` ## Test Coverage @@ -123,4 +122,4 @@ Test outputs are saved to `integration-test/output/`: ## CI Integration -See `.github/workflows/test-windows.yml` and `.github/workflows/test-linux.yml` for CI usage examples. +See `.github/workflows/integration-test-windows.yml` and `.github/workflows/integration-test-linux.yml` for CI usage examples. From 0d0f291be1bccad60501c700214fe5281fa90abe Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 29 Oct 2025 21:36:45 +0200 Subject: [PATCH 43/49] Update app-runner module --- integration-test/CMakeLists.txt | 2 +- integration-test/Integration.Tests.ps1 | 117 +------------------------ 2 files changed, 3 insertions(+), 116 deletions(-) diff --git a/integration-test/CMakeLists.txt b/integration-test/CMakeLists.txt index d505b98b1..2bdf4cee6 100644 --- a/integration-test/CMakeLists.txt +++ b/integration-test/CMakeLists.txt @@ -24,7 +24,7 @@ include(FetchContent) FetchContent_Declare( app-runner GIT_REPOSITORY https://github.com/getsentry/app-runner.git - GIT_TAG 44583d2c37d666d7e9063814491ab475e1c6020b + GIT_TAG 288991e2096a39bda7aaa40f1baf2a65952a5f23 ) FetchContent_MakeAvailable(app-runner) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index bf1e4a8e4..c4c41f5af 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -6,119 +6,6 @@ Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' -function script:Convert-HashtableToObject($item) { - if ($item -is [System.Collections.IDictionary]) { - $obj = [PSCustomObject]@{} - foreach ($key in $item.Keys) { - if ([string]::IsNullOrWhiteSpace($key)) { - continue - } - $obj | Add-Member -NotePropertyName $key -NotePropertyValue (Convert-HashtableToObject $item[$key]) - } - return $obj - } elseif ($item -is [System.Collections.IEnumerable] -and -not ($item -is [string])) { - return @($item | ForEach-Object { Convert-HashtableToObject $_ }) - } else { - return $item - } -} - -function script:Get-SentryUnrealTestEvent { - [CmdletBinding()] - param( - [Parameter()] - [string]$EventId, - - [Parameter()] - [string]$TagName, - - [Parameter()] - [string]$TagValue, - - [Parameter()] - [int]$TimeoutSeconds = 120 - ) - - if ($EventId) { - Write-Host "Fetching Sentry event by ID: $EventId" -ForegroundColor Yellow - $progressActivity = "Waiting for Sentry event $EventId" - } elseif ($TagName -and $TagValue) { - Write-Host "Fetching Sentry event by tag: $TagName=$TagValue" -ForegroundColor Yellow - $progressActivity = "Waiting for Sentry event with tag $TagName=$TagValue" - } else { - throw 'Must specify either EventId or both TagName and TagValue' - } - - $startTime = Get-Date - $endTime = $startTime.AddSeconds($TimeoutSeconds) - $lastError = $null - $elapsedSeconds = 0 - - try { - do { - $sentryEvent = $null - $elapsedSeconds = [int]((Get-Date) - $startTime).TotalSeconds - $percentComplete = [math]::Min(100, ($elapsedSeconds / $TimeoutSeconds) * 100) - - Write-Progress -Activity $progressActivity -Status "Elapsed: $elapsedSeconds/$TimeoutSeconds seconds" -PercentComplete $percentComplete - - try { - if ($EventId) { - # Find by event ID - $sentryEvent = Get-SentryEvent -EventId $EventId - } else { - # Find by tag - $result = Find-SentryEventByTag -TagName $TagName -TagValue $TagValue - $result.Count | Should -Be 1 - $sentryEvent = $result[0] - } - } catch { - $lastError = $_.Exception.Message - # Event not found yet, continue waiting - if ($EventId) { - Write-Debug "Event $EventId not found yet: $lastError" - } else { - Write-Debug "Event with tag $TagName=$TagValue not found yet: $lastError" - } - } - - if ($sentryEvent) { - # Convert from JSON if it's a raw string - if ($sentryEvent -is [string]) { - try { - $raw = $sentryEvent | ConvertFrom-Json -Depth 50 -AsHashTable - # Recursively convert hashtables to PSCustomObjects - $sentryEvent = Convert-HashtableToObject $raw - } catch { - Write-Host "Failed to parse JSON from Sentry event: $($_.Exception.Message)" -ForegroundColor Red - return - } - } - - Write-Host "Event $($sentryEvent.id) fetched from Sentry" -ForegroundColor Green - $entries = $sentryEvent.entries - $sentryEvent = $sentryEvent | Select-Object -ExcludeProperty 'entries' - foreach ($entry in $entries) { - $sentryEvent | Add-Member -MemberType NoteProperty -Name $entry.type -Value $entry.data -Force - } - $sentryEvent | ConvertTo-Json -Depth 10 | Out-File -FilePath (Get-OutputFilePath "event-$($sentryEvent.id).json") - return $sentryEvent - } - - Start-Sleep -Milliseconds 500 - $currentTime = Get-Date - } while ($currentTime -lt $endTime) - } finally { - Write-Progress -Activity $progressActivity -Completed - } - - if ($EventId) { - throw "Event $EventId not found in Sentry within $TimeoutSeconds seconds: $lastError" - } else { - throw "Event with tag $TagName=$TagValue not found in Sentry within $TimeoutSeconds seconds: $lastError" - } -} - function script:Invoke-SentryUnrealTestApp { [CmdletBinding()] param( @@ -255,7 +142,7 @@ Describe "Sentry Unreal Integration Tests" { # Fetch event from Sentry (with polling) try { - $script:CrashEvent = Get-SentryUnrealTestEvent -TagName 'test.crash_id' -TagValue "$crashId" + $script:CrashEvent = Get-SentryTestEvent -TagName 'test.crash_id' -TagValue "$crashId" Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green } catch { Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red @@ -344,7 +231,7 @@ Describe "Sentry Unreal Integration Tests" { # Fetch event from Sentry (with polling) using sanitized helper try { - $script:MessageEvent = Get-SentryUnrealTestEvent -EventId $eventIds[0] + $script:MessageEvent = Get-SentryTestEvent -EventId $eventIds[0] Write-Host "Event fetched from Sentry successfully" -ForegroundColor Green } catch { Write-Host "Failed to fetch event from Sentry: $_" -ForegroundColor Red From cc1d7f513db84fb6464cd6296be5b707b90ea4ab Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 30 Oct 2025 09:02:54 +0200 Subject: [PATCH 44/49] Fix message test check --- integration-test/Integration.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index c4c41f5af..177836434 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -267,7 +267,7 @@ Describe "Sentry Unreal Integration Tests" { It "Should have message content" { $script:MessageEvent.message | Should -Not -BeNullOrEmpty - $script:MessageEvent.message | Should -Match 'Integration test message' + $script:MessageEvent.message.formatted | Should -Match 'Integration test message' } It "Should have user context" { From 5af044b1a47cb19effd52f32263e25abe66e2de3 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 30 Oct 2025 09:15:51 +0200 Subject: [PATCH 45/49] Clean up cmake --- integration-test/CMakeLists.txt | 17 ----------------- integration-test/README.md | 26 ++++++++------------------ 2 files changed, 8 insertions(+), 35 deletions(-) diff --git a/integration-test/CMakeLists.txt b/integration-test/CMakeLists.txt index 2bdf4cee6..5db8d350a 100644 --- a/integration-test/CMakeLists.txt +++ b/integration-test/CMakeLists.txt @@ -1,23 +1,6 @@ cmake_minimum_required(VERSION 3.20) project(SentryUnrealIntegrationTests NONE) -# Only configure if environment variables are set -if(NOT DEFINED ENV{SENTRY_UNREAL_TEST_DSN} OR NOT DEFINED ENV{SENTRY_AUTH_TOKEN}) - if(DEFINED ENV{SENTRY_FORCE_CONFIGURE_INTEGRATION_TEST}) - message(WARNING "Environment variables SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN are not defined but SENTRY_FORCE_CONFIGURE_INTEGRATION_TEST is set.") - else() - message(STATUS "Skipping integration test configuration: SENTRY_UNREAL_TEST_DSN and SENTRY_AUTH_TOKEN must be defined") - - # Delete config file so test script knows to skip - set(configFile "${CMAKE_CURRENT_SOURCE_DIR}/TestConfig.local.ps1") - if(EXISTS ${configFile}) - file(REMOVE ${configFile}) - endif() - - return() - endif() -endif() - include(FetchContent) # Fetch PowerShell modules for Sentry API integration diff --git a/integration-test/README.md b/integration-test/README.md index 1d68f51a5..589f88f91 100644 --- a/integration-test/README.md +++ b/integration-test/README.md @@ -28,19 +28,7 @@ This will: - Download `app-runner` from GitHub (contains SentryApiClient and test utilities) - Generate `TestConfig.local.ps1` with module paths -**Note**: If environment variables are not set, CMake will skip configuration with a warning. Set them first: - -```bash -# Windows PowerShell -$env:SENTRY_UNREAL_TEST_DSN = "https://key@org.ingest.sentry.io/project" -$env:SENTRY_AUTH_TOKEN = "sntrys_your_token_here" -$env:SENTRY_UNREAL_TEST_APP_PATH = "path/to/SentryPlayground.exe" - -# Linux/macOS -export SENTRY_UNREAL_TEST_DSN="https://key@org.ingest.sentry.io/project" -export SENTRY_AUTH_TOKEN="sntrys_your_token_here" -export SENTRY_UNREAL_TEST_APP_PATH="./path/to/SentryPlayground.sh" -``` +**Note**: CMake configuration can be run without setting environment variables. The environment variables are only required at test runtime and will be validated by the test script itself. ### 2. Get SentryPlayground Application @@ -59,12 +47,14 @@ Follow the standard Unreal Engine build process for the [sample](./sample/) proj ## Running Tests +Before running tests, ensure you have set the required environment variables: + ### Windows ```powershell # Set environment variables -$env:SENTRY_UNREAL_TEST_DSN = "https://..." -$env:SENTRY_AUTH_TOKEN = "sntrys_..." +$env:SENTRY_UNREAL_TEST_DSN = "https://key@org.ingest.sentry.io/project" +$env:SENTRY_AUTH_TOKEN = "sntrys_your_token_here" $env:SENTRY_UNREAL_TEST_APP_PATH = "path/to/SentryPlayground.exe" # Run tests @@ -76,8 +66,8 @@ Invoke-Pester Integration.Tests.ps1 ```bash # Set environment variables -export SENTRY_UNREAL_TEST_DSN="https://..." -export SENTRY_AUTH_TOKEN="sntrys_..." +export SENTRY_UNREAL_TEST_DSN="https://key@org.ingest.sentry.io/project" +export SENTRY_AUTH_TOKEN="sntrys_your_token_here" export SENTRY_UNREAL_TEST_APP_PATH="./path/to/SentryPlayground.sh" # Run tests @@ -91,7 +81,7 @@ The integration tests cover: ### Crash Capture Tests - Application crashes with non-zero exit code -- Event ID is captured from output +- Event ID is captured from output (set via `test.crash_id` tag) - Crash event appears in Sentry - Exception information is present - Stack traces are captured From fec56772fa1454a8b2c2d68e53d99c553450a1fd Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 30 Oct 2025 09:46:49 +0200 Subject: [PATCH 46/49] Refactor --- integration-test/Integration.Tests.ps1 | 50 +++++++++++--------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 177836434..0705a165f 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -13,22 +13,25 @@ function script:Invoke-SentryUnrealTestApp { [string[]]$Arguments, [Parameter(Mandatory)] - [string]$StdoutFile, - - [Parameter(Mandatory)] - [string]$StderrFile, + [string]$TestName, [Parameter()] [int]$TimeoutSeconds = 300 ) + # Generate timestamp and output file paths + $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' + $stdoutFile = "$script:OutputDir/$timestamp-$TestName-stdout.log" + $stderrFile = "$script:OutputDir/$timestamp-$TestName-stderr.log" + $resultFile = "$script:OutputDir/$timestamp-$TestName-result.json" + $exitCode = -1 try { $process = Start-Process -FilePath $script:AppPath -ArgumentList $Arguments ` -PassThru -NoNewWindow ` - -RedirectStandardOutput $StdoutFile ` - -RedirectStandardError $StderrFile + -RedirectStandardOutput $stdoutFile ` + -RedirectStandardError $stderrFile if ($process.WaitForExit($TimeoutSeconds * 1000)) { $exitCode = $process.ExitCode @@ -46,19 +49,24 @@ function script:Invoke-SentryUnrealTestApp { $stdout = @() $stderr = @() - if (Test-Path $StdoutFile) { - $stdout = Get-Content $StdoutFile -ErrorAction SilentlyContinue + if (Test-Path $stdoutFile) { + $stdout = Get-Content $stdoutFile -ErrorAction SilentlyContinue } - if (Test-Path $StderrFile) { - $stderr = Get-Content $StderrFile -ErrorAction SilentlyContinue + if (Test-Path $stderrFile) { + $stderr = Get-Content $stderrFile -ErrorAction SilentlyContinue } - return @{ + $result = @{ ExitCode = $exitCode Output = $stdout Error = $stderr } + + # Save full output to result JSON + $result | ConvertTo-Json -Depth 10 | Out-File $resultFile + + return $result } BeforeAll { @@ -116,19 +124,11 @@ Describe "Sentry Unreal Integration Tests" { Write-Host "Running crash capture test..." -ForegroundColor Yellow - # Prepare output files - $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' - $stdoutFile = "$script:OutputDir/$timestamp-crash-stdout.log" - $stderrFile = "$script:OutputDir/$timestamp-crash-stderr.log" - # Build arguments and execute application # -stdout ensures logs are written to stdout on Linux/Unix systems # -nosplash prevents splash screen and dialogs $appArgs = @('-crash-capture', '-NullRHI', '-unattended', '-stdout', '-nosplash') - $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile - - # Save full output - $script:CrashResult | ConvertTo-Json -Depth 10 | Out-File "$script:OutputDir/$timestamp-crash-result.json" + $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -TestName 'crash' Write-Host "Crash test executed. Exit code: $($script:CrashResult.ExitCode)" -ForegroundColor Cyan @@ -207,19 +207,11 @@ Describe "Sentry Unreal Integration Tests" { Write-Host "Running message capture test..." -ForegroundColor Yellow - # Prepare output files - $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' - $stdoutFile = "$script:OutputDir/$timestamp-message-stdout.log" - $stderrFile = "$script:OutputDir/$timestamp-message-stderr.log" - # Build arguments and execute application # -stdout ensures logs are written to stdout on Linux/Unix systems # -nosplash prevents splash screen and dialogs $appArgs = @('-message-capture', '-NullRHI', '-unattended', '-stdout', '-nosplash') - $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -StdoutFile $stdoutFile -StderrFile $stderrFile - - # Save full output - $script:MessageResult | ConvertTo-Json -Depth 10 | Out-File "$script:OutputDir/$timestamp-message-result.json" + $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -TestName 'message' Write-Host "Message test executed. Exit code: $($script:MessageResult.ExitCode)" -ForegroundColor Cyan From e56d5286736f0b1d89a0327d95d2687f9123baaf Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 30 Oct 2025 09:48:36 +0200 Subject: [PATCH 47/49] Comments --- integration-test/Integration.Tests.ps1 | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/integration-test/Integration.Tests.ps1 b/integration-test/Integration.Tests.ps1 index 0705a165f..dfd59e9de 100644 --- a/integration-test/Integration.Tests.ps1 +++ b/integration-test/Integration.Tests.ps1 @@ -124,10 +124,13 @@ Describe "Sentry Unreal Integration Tests" { Write-Host "Running crash capture test..." -ForegroundColor Yellow - # Build arguments and execute application - # -stdout ensures logs are written to stdout on Linux/Unix systems - # -nosplash prevents splash screen and dialogs - $appArgs = @('-crash-capture', '-NullRHI', '-unattended', '-stdout', '-nosplash') + # Build arguments and execute application: + # -crash-capture: Triggers integration test crash scenario in the sample app + # -nullrhi: Runs without graphics rendering (headless mode) + # -unattended: Disables user prompts and interactive dialogs + # -stdout: Ensures logs are written to stdout on Linux/Unix systems + # -nosplash: Prevents splash screen and dialogs + $appArgs = @('-crash-capture', '-nullrhi', '-unattended', '-stdout', '-nosplash') $script:CrashResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -TestName 'crash' Write-Host "Crash test executed. Exit code: $($script:CrashResult.ExitCode)" -ForegroundColor Cyan @@ -207,10 +210,13 @@ Describe "Sentry Unreal Integration Tests" { Write-Host "Running message capture test..." -ForegroundColor Yellow - # Build arguments and execute application - # -stdout ensures logs are written to stdout on Linux/Unix systems - # -nosplash prevents splash screen and dialogs - $appArgs = @('-message-capture', '-NullRHI', '-unattended', '-stdout', '-nosplash') + # Build arguments and execute application: + # -message-capture: Triggers integration test message scenario in the sample app + # -nullrhi: Runs without graphics rendering (headless mode) + # -unattended: Disables user prompts and interactive dialogs + # -stdout: Ensures logs are written to stdout on Linux/Unix systems + # -nosplash: Prevents splash screen and dialogs + $appArgs = @('-message-capture', '-nullrhi', '-unattended', '-stdout', '-nosplash') $script:MessageResult = Invoke-SentryUnrealTestApp -Arguments $appArgs -TestName 'message' Write-Host "Message test executed. Exit code: $($script:MessageResult.ExitCode)" -ForegroundColor Cyan From 09c8cc6b540e9994f52b8787bb6f8e474cad5dad Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 30 Oct 2025 09:49:58 +0200 Subject: [PATCH 48/49] Include sources for symbol upload in sample --- sample/Config/DefaultEngine.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/sample/Config/DefaultEngine.ini b/sample/Config/DefaultEngine.ini index 66348e797..bca84ad7e 100644 --- a/sample/Config/DefaultEngine.ini +++ b/sample/Config/DefaultEngine.ini @@ -230,6 +230,7 @@ bGeneratedSYMBundle=True [/Script/Sentry.SentrySettings] CrashReporterUrl="https://o447951.ingest.sentry.io/api/6253052/unreal/93c7a68867db43539980de54f09b139a/" Dsn="https://93c7a68867db43539980de54f09b139a@o447951.ingest.sentry.io/6253052" +IncludeSources=True [/Script/MacTargetPlatform.XcodeProjectSettings] BundleIdentifier=io.sentry.unreal.sample From 7af930cb817ff5a555616a2186b2f382f3b5b8ca Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 30 Oct 2025 14:20:05 +0200 Subject: [PATCH 49/49] Update app-runner `GIT_TAG` to latest version --- integration-test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-test/CMakeLists.txt b/integration-test/CMakeLists.txt index 5db8d350a..ec54093bc 100644 --- a/integration-test/CMakeLists.txt +++ b/integration-test/CMakeLists.txt @@ -7,7 +7,7 @@ include(FetchContent) FetchContent_Declare( app-runner GIT_REPOSITORY https://github.com/getsentry/app-runner.git - GIT_TAG 288991e2096a39bda7aaa40f1baf2a65952a5f23 + GIT_TAG 503795f0ef0f8340fcc0f0bc5fb5437df8cff9ef ) FetchContent_MakeAvailable(app-runner)