From 38f16f9240d22f586013c0ecbe3b146ad7e47c8d Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 14:05:07 +0300 Subject: [PATCH 01/20] Update sample project to run integration tests --- .../SentryPlayground/SentryPlayground.cpp | 2 + .../SentryPlayground/SentryPlayground.h | 2 + .../SentryPlaygroundGameInstance.cpp | 99 +++++++++++++++++++ .../SentryPlaygroundGameInstance.h | 12 +++ 4 files changed, 115 insertions(+) diff --git a/sample/Source/SentryPlayground/SentryPlayground.cpp b/sample/Source/SentryPlayground/SentryPlayground.cpp index d2101222e..28f969aa9 100644 --- a/sample/Source/SentryPlayground/SentryPlayground.cpp +++ b/sample/Source/SentryPlayground/SentryPlayground.cpp @@ -4,3 +4,5 @@ #include "Modules/ModuleManager.h" IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, SentryPlayground, "SentryPlayground" ); + +DEFINE_LOG_CATEGORY(LogSentrySample); diff --git a/sample/Source/SentryPlayground/SentryPlayground.h b/sample/Source/SentryPlayground/SentryPlayground.h index 37143a4de..f454875cc 100644 --- a/sample/Source/SentryPlayground/SentryPlayground.h +++ b/sample/Source/SentryPlayground/SentryPlayground.h @@ -4,3 +4,5 @@ #include "CoreMinimal.h" +DECLARE_LOG_CATEGORY_EXTERN(LogSentrySample, Verbose, All); + diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 6898c0eb2..f9bb26213 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -2,9 +2,108 @@ #include "SentryPlaygroundGameInstance.h" +#include "SentryPlayground.h" #include "SentrySubsystem.h" +#include "SentrySettings.h" +#include "SentryPlaygroundUtils.h" +#include "SentryUser.h" + +#include "Misc/CommandLine.h" +#include "Engine/Engine.h" void USentryPlaygroundGameInstance::Init() { Super::Init(); + + const TCHAR* CommandLine = FCommandLine::Get(); + + // Check '-Test' commandline argument to decide between running integration tests + // or launching the sample app with UI for manual testing + if (FParse::Param(FCommandLine::Get(), TEXT("Test"))) + { + RunIntegrationTest(CommandLine); + } +} + +void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) +{ + UE_LOG(LogSentrySample, Log, TEXT("Running integration test for command: %s\n"), CommandLine); + + USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + if (!SentrySubsystem) + { + CompleteTestWithResult(TEXT("sentry-error"), false, TEXT("Invalid Sentry subsystem")); + return; + } + + SentrySubsystem->InitializeWithSettings(FConfigureSettingsNativeDelegate::CreateLambda([=](USentrySettings* Settings) + { + // Override options set in config file + })); + + if (!SentrySubsystem->IsEnabled()) + { + CompleteTestWithResult(TEXT("sentry-error"), false, TEXT("Failed to initialize Sentry")); + return; + } + + SentrySubsystem->AddBreadcrumbWithParams( + TEXT("Integration test started"), TEXT("Test"), TEXT("info"), TMap(), ESentryLevel::Info); + + ConfigureTestContext(); + + SentrySubsystem->AddBreadcrumbWithParams( + TEXT("Context configuration finished"), TEXT("Test"), TEXT("info"), TMap(), ESentryLevel::Info); + + if (FParse::Param(CommandLine, TEXT("CrashCapture"))) + { + RunCrashTest(); + } + else if (FParse::Param(CommandLine, TEXT("MessageCapture"))) + { + RunMessageTest(); + } + + // Integration test requested but no action specified + CompleteTestWithResult(TEXT("invalid-command"), false, TEXT("Missing command")); +} + +void USentryPlaygroundGameInstance::RunCrashTest() +{ + USentryPlaygroundUtils::Terminate(ESentryAppTerminationType::NullPointer); +} + +void USentryPlaygroundGameInstance::RunMessageTest() +{ + USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + + FString EventId = SentrySubsystem->CaptureMessage(TEXT("Integration test message")); + + UE_LOG(LogSentrySample, Log, TEXT("EVENT_CAPTURED: %s\n"), *EventId); + + CompleteTestWithResult("message-capture", !EventId.IsEmpty(), "Test complete"); +} + +void USentryPlaygroundGameInstance::ConfigureTestContext() +{ + USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + + USentryUser* User = NewObject(); + User->Initialize(); + User->SetUsername(TEXT("TestUser")); + User->SetEmail(TEXT("user-mail@test.abc")); + User->SetId(TEXT("12345")); + + SentrySubsystem->SetUser(User); + + SentrySubsystem->SetTag(TEXT("test.suite"), TEXT("integration")); +} + +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"), + *TestName, Result ? TEXT("true") : TEXT("false"), *Message); + + // Close app after test is completed + FGenericPlatformMisc::RequestExit(false); } diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h index 5381d662f..59f5672d2 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.h @@ -4,6 +4,8 @@ #include "CoreMinimal.h" #include "Engine/GameInstance.h" +#include "SentryPlaygroundUtils.h" +#include "SentrySubsystem.h" #include "SentryPlaygroundGameInstance.generated.h" /** @@ -14,5 +16,15 @@ class SENTRYPLAYGROUND_API USentryPlaygroundGameInstance : public UGameInstance { GENERATED_BODY() +public: virtual void Init() override; + +private: + void RunIntegrationTest(const TCHAR* CommandLine); + void RunCrashTest(); + void RunMessageTest(); + + void ConfigureTestContext(); + + void CompleteTestWithResult(const FString& TestName, bool Result, const FString& Message); }; From 324102b05056e96721efd529bcc8884a7fe50196 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 14:23:18 +0300 Subject: [PATCH 02/20] Cleanup test run in ci and upload sample build --- .github/workflows/test-linux.yml | 19 ++++++------------- .github/workflows/test-windows.yml | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index cee0fddf6..d57467ea1 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -118,8 +118,6 @@ jobs: env: EDITOR_BINARY: ${{ inputs.unreal-version == '4.27' && 'UE4Editor' || 'UnrealEditor' }} run: | - docker exec -w /workspace/checkout/sample unreal bash -c " - ls -al /workspace/checkout/sample/Plugins/sentry " docker exec -w /workspace/checkout/sample unreal /home/ue4/UnrealEngine/Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \ -project=/workspace/checkout/sample/SentryPlayground.uproject \ -archivedirectory=/workspace/checkout/sample/Builds \ @@ -131,8 +129,6 @@ jobs: -prereqss \ -package \ -archive - docker exec -w /workspace/checkout/sample unreal bash -c " - cp -r '/home/gh/Library/Logs/Unreal Engine/LocalBuildLogs' Saved/Logs " docker exec -w /workspace/checkout/sample unreal /home/ue4/UnrealEngine/Engine/Binaries/Linux/"$EDITOR_BINARY" \ /workspace/checkout/sample/SentryPlayground.uproject \ -ReportExportPath=/workspace/checkout/sample/Saved/Automation \ @@ -147,17 +143,14 @@ jobs: if: ${{ always() && steps.run-tests.outcome == 'failure' }} uses: actions/upload-artifact@v4 with: - name: UE ${{ inputs.unreal-version }} sample test report + name: UE ${{ inputs.unreal-version }} sample test report (Linux) path: | checkout/sample/Saved/Automation - - name: Collect sample build info - if: contains(fromJson('["success", "failure"]'), steps.run-tests.outcome) + - name: Upload sample build + if: ${{ success() && steps.run-tests.outcome == 'success' }} uses: actions/upload-artifact@v4 with: - name: UE ${{ inputs.unreal-version }} sample build logs - path: | - checkout/sample/Saved/Logs - checkout/sample/Saved/Stats - checkout/sample/Saved/MaterialStats - checkout/sample/Saved/MaterialStatsDebug + name: UE ${{ inputs.unreal-version }} sample build (Linux) + path: /checkout/sample/Builds/Linux/ + retention-days: 1 diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 89bb4a20c..2698ab522 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -79,3 +79,20 @@ jobs: -NoPause ` -NoSplash ` -NullRHI + + - name: Collect sample test info + if: ${{ always() && steps.run-tests.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} sample test report (Windows) + path: | + C:/workspace/checkout/sample/Saved/Automation + + - name: Upload sample build + if: ${{ success() && steps.run-tests.outcome == 'success' }} + uses: actions/upload-artifact@v4 + with: + name: UE ${{ inputs.unreal-version }} sample build (Windows) + path: /checkout/sample/Builds/Windows/ + retention-days: 1 + From 318590c2b7b25ee384335e76465270456bc472d4 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 16:02:21 +0300 Subject: [PATCH 03/20] Add sample project readme --- sample/README.md | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 sample/README.md diff --git a/sample/README.md b/sample/README.md new file mode 100644 index 000000000..5edc393b1 --- /dev/null +++ b/sample/README.md @@ -0,0 +1,88 @@ +

+ + + +
+

+

+ +Sentry Unreal Engine SDK Sample Project +=========== + +This sample project demonstrates the capabilities of the Sentry Unreal Engine SDK and provides a comprehensive testing environment for all SDK features. + +## Getting started + +### Prerequisites + +- Unreal Engine 4.27 or newer (version configured in `SentryPlayground.uproject`) +- Platform support: Windows, macOS, Linux, Android, iOS, PlayStation 5, Xbox, Nintendo Switch +- Sentry account with a project and DSN + +### Setup + +- Clone or download the Sentry Unreal SDK repository +- Copy or symlink the Sentry plugin sources to `sample/Plugins/Sentry/` +- Open `SentryPlayground.uproject` in Unreal Engine +- Configure your Sentry DSN in `Config/DefaultEngine.ini` or through the project settings menu +- Play the `SentryDemo` level to begin testing + +## Project structure overview + +Here's a breakdown of the important sample project files and folders: + +📁 sample +├── 📄 SentryPlayground.uproject (Engine version configuration, supports UE 4.27 and newer) +├── 📁 Source/ +│ └── 📁 SentryPlayground/ +│ ├── 📄 SentryPlaygroundGameInstance.cpp/.h (Logic for running integration tests) +│ ├── 📄 SentryPlaygroundUtils.cpp/.h (Utilities for triggering different types of crashes) +│ ├── 📄 CppBeforeSendHandler.cpp/.h (Example C++ implementation of `beforeSend` hook handler) +│ └── 📄 SentryGCCallback.cpp/.h (Utility for capturing events during garbage collection) +├── 📁 Content/ +│ ├── 📁 Maps/ +│ │ └── 📄 SentryDemo.umap (Main demo level) +│ ├── 📁 UI/ +│ │ └── 📄 W_SentryDemo.uasset (Demo UI widget for testing SDK features) +│ └── 📁 Misc/ +│ ├── 📄 BP_BeforeSendHandler.uasset (Example Blueprint implementation of `beforeSend` hook handler) +│ ├── 📄 BP_BeforeBreadcrumbHandler.uasset (Example Blueprint implementation of `beforeBreadcrumb` hook handler) +│ └── 📄 BP_TraceSampler.uasset (Example Blueprint implementation of traces sampling function) +├── 📁 Config/ +│ └── 📄 DefaultEngine.ini (Configuration file with Sentry plugin settings) +└── 📁 Plugins/ (Location for Sentry SDK sources - copy or symlink here) + + +## Demo Level + +The demo level (`SentryDemo.umap`) in the project's Content folder presents a simple UI for sending test events to Sentry. The `W_SentryDemo` Blueprint implementation demonstrates how to call the plugin API and serves as a reference. + +To run the demo level, navigate to `Content Browser -> Content -> Maps` and open the `SentryDemo` map. Click Play to launch the demo. + +## Unit Tests + +To run automation tests, several engine plugins are enabled (see `Settings -> Plugins -> Testing`). Navigate to `Windows -> Test Automation` menu and open the `Session Frontend` window. Switch to the `Automation` tab and select `Sentry` from the list of available tests. Click the `Start Tests` button to run the tests and check the results. + +## Integration Tests + +The `SentryPlaygroundGameInstance.cpp` file contains logic that parses command line input used to launch the sample game build and runs test actions accordingly (e.g., trigger crash, capture message). Here are example commands: + +```pwsh +# Windows - Crash capture test +SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -CrashCapture + +# Windows - Message capture test +SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -MessageCapture +``` + +To run integration tests, ensure the `-Test` argument is passed to the executable and specify which test to run with the appropriate argument. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. + +## Example Content + +The sample project contains example Blueprint implementations of various hook handlers under `Content -> Misc`: + +- `BP_BeforeSendHandler` - Example Blueprint implementation of event filtering +- `BP_BeforeBreadcrumbHandler` - Custom breadcrumb processing logic +- `BP_TraceSampler` - Performance monitoring sampling configuration + +These can be configured for the SDK to use in `Project Settings -> Plugins -> Sentry`. \ No newline at end of file From 6ec01f74ed493ed29be71d57ec96724deabb8484 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 16:02:32 +0300 Subject: [PATCH 04/20] Move assets --- .../BP_BeforeBreadcrumbHandler.uasset | Bin 21927 -> 0 bytes .../Misc/BP_BeforeBreadcrumbHandler.uasset | Bin 0 -> 22310 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 sample/Content/Blueprints/BP_BeforeBreadcrumbHandler.uasset create mode 100644 sample/Content/Misc/BP_BeforeBreadcrumbHandler.uasset diff --git a/sample/Content/Blueprints/BP_BeforeBreadcrumbHandler.uasset b/sample/Content/Blueprints/BP_BeforeBreadcrumbHandler.uasset deleted file mode 100644 index 2b89d54040b0091a90387cf4e0f537dbf3d7d3fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21927 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 WRBD6h)9!D^=1WxlYd8Hu?*9S3&jG~% literal 0 HcmV?d00001 From 28bac1017c8e7d8aeb8a9f5612bbff1b6bd2c2e4 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 16:02:44 +0300 Subject: [PATCH 05/20] Fix contriburing guide --- CONTRIBUTING.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18b616992..809993dc8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,10 +50,9 @@ In order to run the demo level navigate to `Content Browser -> Content -> Maps` ## Modifying plugin content -All files that belong to the plugin are listed in the snapshot files: +All files that belong to the plugin are listed in the snapshot file: -- `/scripts/packaging/package-github.snapshot` (for the GitHub package) -- `/scripts/packaging/package-marketplace.snapshot` (for the Marketplace package) +- `/scripts/packaging/package.snapshot` If you add, delete or move files within the `plugin-dev` directory these snapshot files must be updated to reflect the changes. To do that, run: From 95d0c7e0bea833787f873412307bc8c4e3c46b12 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 16:08:33 +0300 Subject: [PATCH 06/20] Fix path --- .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 d57467ea1..e44113caa 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -152,5 +152,5 @@ jobs: uses: actions/upload-artifact@v4 with: name: UE ${{ inputs.unreal-version }} sample build (Linux) - path: /checkout/sample/Builds/Linux/ + path: checkout/sample/Builds/Linux/ retention-days: 1 diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 2698ab522..97c1a25e8 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -93,6 +93,6 @@ jobs: uses: actions/upload-artifact@v4 with: name: UE ${{ inputs.unreal-version }} sample build (Windows) - path: /checkout/sample/Builds/Windows/ + path: checkout/sample/Builds/Windows/ retention-days: 1 From 63e2feadc750b0d91bcd8a01ae1a63d878e48691 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 16:10:15 +0300 Subject: [PATCH 07/20] Fix file tree --- sample/README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sample/README.md b/sample/README.md index 5edc393b1..3fea05fa0 100644 --- a/sample/README.md +++ b/sample/README.md @@ -31,27 +31,28 @@ This sample project demonstrates the capabilities of the Sentry Unreal Engine SD Here's a breakdown of the important sample project files and folders: +``` 📁 sample -├── 📄 SentryPlayground.uproject (Engine version configuration, supports UE 4.27 and newer) +├── 📄 SentryPlayground.uproject (Engine version configuration, supports UE 4.27 and newer) ├── 📁 Source/ │ └── 📁 SentryPlayground/ -│ ├── 📄 SentryPlaygroundGameInstance.cpp/.h (Logic for running integration tests) -│ ├── 📄 SentryPlaygroundUtils.cpp/.h (Utilities for triggering different types of crashes) -│ ├── 📄 CppBeforeSendHandler.cpp/.h (Example C++ implementation of `beforeSend` hook handler) -│ └── 📄 SentryGCCallback.cpp/.h (Utility for capturing events during garbage collection) +│ ├── 📄 SentryPlaygroundGameInstance.cpp/.h (Logic for running integration tests) +│ ├── 📄 SentryPlaygroundUtils.cpp/.h (Utilities for triggering different types of crashes) +│ ├── 📄 CppBeforeSendHandler.cpp/.h (Example C++ implementation of `beforeSend` hook handler) +│ └── 📄 SentryGCCallback.cpp/.h (Utility for capturing events during garbage collection) ├── 📁 Content/ │ ├── 📁 Maps/ -│ │ └── 📄 SentryDemo.umap (Main demo level) +│ │ └── 📄 SentryDemo.umap (Main demo level) │ ├── 📁 UI/ -│ │ └── 📄 W_SentryDemo.uasset (Demo UI widget for testing SDK features) +│ │ └── 📄 W_SentryDemo.uasset (Demo UI widget for testing SDK features) │ └── 📁 Misc/ -│ ├── 📄 BP_BeforeSendHandler.uasset (Example Blueprint implementation of `beforeSend` hook handler) -│ ├── 📄 BP_BeforeBreadcrumbHandler.uasset (Example Blueprint implementation of `beforeBreadcrumb` hook handler) -│ └── 📄 BP_TraceSampler.uasset (Example Blueprint implementation of traces sampling function) +│ ├── 📄 BP_BeforeSendHandler.uasset (Example Blueprint implementation of `beforeSend` hook handler) +│ ├── 📄 BP_BeforeBreadcrumbHandler.uasset (Example Blueprint implementation of `beforeBreadcrumb` hook handler) +│ └── 📄 BP_TraceSampler.uasset (Example Blueprint implementation of traces sampling function) ├── 📁 Config/ -│ └── 📄 DefaultEngine.ini (Configuration file with Sentry plugin settings) -└── 📁 Plugins/ (Location for Sentry SDK sources - copy or symlink here) - +│ └── 📄 DefaultEngine.ini (Configuration file with Sentry plugin settings) +└── 📁 Plugins/ (Location for Sentry SDK sources - copy or symlink here) +``` ## Demo Level From 4ba0adbc88b0116a8f6b70d2fc2c64ce0c06ecc3 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Tue, 2 Sep 2025 16:33:29 +0300 Subject: [PATCH 08/20] Update readme --- sample/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/sample/README.md b/sample/README.md index 3fea05fa0..e60e5bd9c 100644 --- a/sample/README.md +++ b/sample/README.md @@ -31,27 +31,27 @@ This sample project demonstrates the capabilities of the Sentry Unreal Engine SD Here's a breakdown of the important sample project files and folders: -``` +```pwsh 📁 sample -├── 📄 SentryPlayground.uproject (Engine version configuration, supports UE 4.27 and newer) +├── 📄 SentryPlayground.uproject # Engine version configuration, supports UE 4.27 and newer ├── 📁 Source/ │ └── 📁 SentryPlayground/ -│ ├── 📄 SentryPlaygroundGameInstance.cpp/.h (Logic for running integration tests) -│ ├── 📄 SentryPlaygroundUtils.cpp/.h (Utilities for triggering different types of crashes) -│ ├── 📄 CppBeforeSendHandler.cpp/.h (Example C++ implementation of `beforeSend` hook handler) -│ └── 📄 SentryGCCallback.cpp/.h (Utility for capturing events during garbage collection) +│ ├── 📄 SentryPlaygroundGameInstance.cpp/.h # Logic for running integration tests +│ ├── 📄 SentryPlaygroundUtils.cpp/.h # Utilities for triggering different types of crashes +│ ├── 📄 CppBeforeSendHandler.cpp/.h # Example C++ implementation of `beforeSend` hook handler +│ └── 📄 SentryGCCallback.cpp/.h # Utility for capturing events during garbage collection ├── 📁 Content/ │ ├── 📁 Maps/ -│ │ └── 📄 SentryDemo.umap (Main demo level) +│ │ └── 📄 SentryDemo.umap # Main demo level) │ ├── 📁 UI/ -│ │ └── 📄 W_SentryDemo.uasset (Demo UI widget for testing SDK features) +│ │ └── 📄 W_SentryDemo.uasset # Demo UI widget for testing SDK features │ └── 📁 Misc/ -│ ├── 📄 BP_BeforeSendHandler.uasset (Example Blueprint implementation of `beforeSend` hook handler) -│ ├── 📄 BP_BeforeBreadcrumbHandler.uasset (Example Blueprint implementation of `beforeBreadcrumb` hook handler) -│ └── 📄 BP_TraceSampler.uasset (Example Blueprint implementation of traces sampling function) +│ ├── 📄 BP_BeforeSendHandler.uasset # Example Blueprint implementation of `beforeSend` hook handler +│ ├── 📄 BP_BeforeBreadcrumbHandler.uasset # Example Blueprint implementation of `beforeBreadcrumb` hook handler +│ └── 📄 BP_TraceSampler.uasset # Example Blueprint implementation of traces sampling function ├── 📁 Config/ -│ └── 📄 DefaultEngine.ini (Configuration file with Sentry plugin settings) -└── 📁 Plugins/ (Location for Sentry SDK sources - copy or symlink here) +│ └── 📄 DefaultEngine.ini # Configuration file with Sentry plugin settings +└── 📁 Plugins/ # Location for Sentry SDK sources - copy or symlink here ``` ## Demo Level @@ -76,7 +76,7 @@ SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -CrashCapture SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -MessageCapture ``` -To run integration tests, ensure the `-Test` argument is passed to the executable and specify which test to run with the appropriate argument. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. +To run integration tests, ensure the `-Test` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. ## Example Content From e17bc018f87de470bbed70d8119077dea3a0573d Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 3 Sep 2025 13:21:42 +0300 Subject: [PATCH 09/20] Add dsn arg for integration tests sample --- sample/README.md | 4 +++- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sample/README.md b/sample/README.md index e60e5bd9c..d5de5a982 100644 --- a/sample/README.md +++ b/sample/README.md @@ -70,7 +70,7 @@ The `SentryPlaygroundGameInstance.cpp` file contains logic that parses command l ```pwsh # Windows - Crash capture test -SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -CrashCapture +SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -CrashCapture -Dsn="your-dsn-here" # Windows - Message capture test SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -MessageCapture @@ -78,6 +78,8 @@ SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -MessageCapture To run integration tests, ensure the `-Test` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. +Optionally, you can override the DSN for integration tests by adding `-Dsn="your-dsn-here"` to the command line. When provided, this DSN will be used instead of the one configured in the project settings. + ## Example Content The sample project contains example Blueprint implementations of various hook handlers under `Content -> Misc`: diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index f9bb26213..38e0b6048 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -38,7 +38,12 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) SentrySubsystem->InitializeWithSettings(FConfigureSettingsNativeDelegate::CreateLambda([=](USentrySettings* Settings) { - // Override options set in config file + // Override options set in config file if needed + FString Dsn; + if (FParse::Value(CommandLine, TEXT("Dsn="), Dsn)) + { + Settings->Dsn = Dsn; + } })); if (!SentrySubsystem->IsEnabled()) From 697a5497fc53802334b5a402207b098b6d7a8968 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 3 Sep 2025 13:45:09 +0300 Subject: [PATCH 10/20] Sample build upload for UE 4.27 --- .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 e44113caa..41c690603 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -152,5 +152,5 @@ jobs: uses: actions/upload-artifact@v4 with: name: UE ${{ inputs.unreal-version }} sample build (Linux) - path: checkout/sample/Builds/Linux/ + path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'LinuxNoEditor' || 'Linux' }}/ retention-days: 1 diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 97c1a25e8..a9558a422 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -93,6 +93,6 @@ jobs: uses: actions/upload-artifact@v4 with: name: UE ${{ inputs.unreal-version }} sample build (Windows) - path: checkout/sample/Builds/Windows/ + path: checkout/sample/Builds/${{ inputs.unreal-version == '4.27' && 'WindowsNoEditor' || 'Windows' }}/ retention-days: 1 From d5676509cd1dd80d6d963daa3e3239ff272f1856 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 3 Sep 2025 13:45:29 +0300 Subject: [PATCH 11/20] Rename arg --- sample/README.md | 6 +++--- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sample/README.md b/sample/README.md index d5de5a982..14b28f150 100644 --- a/sample/README.md +++ b/sample/README.md @@ -70,13 +70,13 @@ The `SentryPlaygroundGameInstance.cpp` file contains logic that parses command l ```pwsh # Windows - Crash capture test -SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -CrashCapture -Dsn="your-dsn-here" +SentryPlayground.exe -nullrhi -unattended -log -SentryIntegrationTest -CrashCapture -Dsn="your-dsn-here" # Windows - Message capture test -SentryPlayground.exe -nullrhi -unattended -stdout -log -Test -MessageCapture +SentryPlayground.exe -nullrhi -unattended -log -SentryIntegrationTest -MessageCapture ``` -To run integration tests, ensure the `-Test` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. +To run integration tests, ensure the `-SentryIntegrationTest` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. Optionally, you can override the DSN for integration tests by adding `-Dsn="your-dsn-here"` to the command line. When provided, this DSN will be used instead of the one configured in the project settings. diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 38e0b6048..4bd533f2d 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -17,9 +17,9 @@ void USentryPlaygroundGameInstance::Init() const TCHAR* CommandLine = FCommandLine::Get(); - // Check '-Test' commandline argument to decide between running integration tests + // Check '-SentryIntegrationTest' commandline argument to decide between running integration tests // or launching the sample app with UI for manual testing - if (FParse::Param(FCommandLine::Get(), TEXT("Test"))) + if (FParse::Param(FCommandLine::Get(), TEXT("SentryIntegrationTest"))) { RunIntegrationTest(CommandLine); } From 02252c43f9f662886ffe3439e7c52f8a9cd195b2 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 3 Sep 2025 14:26:26 +0300 Subject: [PATCH 12/20] FIx multiple exit requests --- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 4bd533f2d..ead59e42f 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -68,9 +68,11 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) { RunMessageTest(); } - - // Integration test requested but no action specified - CompleteTestWithResult(TEXT("invalid-command"), false, TEXT("Missing command")); + else + { + // Integration test requested but no action specified + CompleteTestWithResult(TEXT("invalid-command"), false, TEXT("Missing command")); + } } void USentryPlaygroundGameInstance::RunCrashTest() From 2bff464321371bdd121f16afa8ac3f5ffaf2d382 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Wed, 3 Sep 2025 14:32:00 +0300 Subject: [PATCH 13/20] Fix test reports path --- .github/workflows/test-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index a9558a422..d6a0c5cb6 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -86,7 +86,7 @@ jobs: with: name: UE ${{ inputs.unreal-version }} sample test report (Windows) path: | - C:/workspace/checkout/sample/Saved/Automation + checkout/sample/Saved/Automation - name: Upload sample build if: ${{ success() && steps.run-tests.outcome == 'success' }} From a0d7a8c886ea3a0abdd67e6352309d9966ca5c5f Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 09:17:16 +0300 Subject: [PATCH 14/20] Rename command line args to align with consoles ci naming --- sample/README.md | 8 ++++---- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sample/README.md b/sample/README.md index 14b28f150..a34176f8f 100644 --- a/sample/README.md +++ b/sample/README.md @@ -70,15 +70,15 @@ The `SentryPlaygroundGameInstance.cpp` file contains logic that parses command l ```pwsh # Windows - Crash capture test -SentryPlayground.exe -nullrhi -unattended -log -SentryIntegrationTest -CrashCapture -Dsn="your-dsn-here" +SentryPlayground.exe -nullrhi -unattended -log -integration-test -crash-capture -dsn="your-dsn-here" # Windows - Message capture test -SentryPlayground.exe -nullrhi -unattended -log -SentryIntegrationTest -MessageCapture +SentryPlayground.exe -nullrhi -unattended -log -integration-test -message-capture ``` -To run integration tests, ensure the `-SentryIntegrationTest` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. +To run integration tests, ensure the `-integration-test` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. -Optionally, you can override the DSN for integration tests by adding `-Dsn="your-dsn-here"` to the command line. When provided, this DSN will be used instead of the one configured in the project settings. +Optionally, you can override the DSN for integration tests by adding `-dsn="your-dsn-here"` to the command line. When provided, this DSN will be used instead of the one configured in the project settings. ## Example Content diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index ead59e42f..b47e3fa47 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -17,9 +17,9 @@ void USentryPlaygroundGameInstance::Init() const TCHAR* CommandLine = FCommandLine::Get(); - // Check '-SentryIntegrationTest' commandline argument to decide between running integration tests + // Check '-integration-test' commandline argument to decide between running integration tests // or launching the sample app with UI for manual testing - if (FParse::Param(FCommandLine::Get(), TEXT("SentryIntegrationTest"))) + if (FParse::Param(FCommandLine::Get(), TEXT("integration-test"))) { RunIntegrationTest(CommandLine); } @@ -40,7 +40,7 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) { // Override options set in config file if needed FString Dsn; - if (FParse::Value(CommandLine, TEXT("Dsn="), Dsn)) + if (FParse::Value(CommandLine, TEXT("dsn="), Dsn)) { Settings->Dsn = Dsn; } @@ -60,11 +60,11 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) SentrySubsystem->AddBreadcrumbWithParams( TEXT("Context configuration finished"), TEXT("Test"), TEXT("info"), TMap(), ESentryLevel::Info); - if (FParse::Param(CommandLine, TEXT("CrashCapture"))) + if (FParse::Param(CommandLine, TEXT("crash-capture"))) { RunCrashTest(); } - else if (FParse::Param(CommandLine, TEXT("MessageCapture"))) + else if (FParse::Param(CommandLine, TEXT("message-capture"))) { RunMessageTest(); } From de625955164d95db29736919e6281cec7a014958 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 09:49:48 +0300 Subject: [PATCH 15/20] Set fake event id for test crash event --- .../SentryPlayground/SentryPlaygroundGameInstance.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index b47e3fa47..5caeed55f 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -77,6 +77,12 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) void USentryPlaygroundGameInstance::RunCrashTest() { + USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + + // 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 + SentrySubsystem->SetTag(TEXT("test.crash_id"), FGuid::NewGuid().ToString(EGuidFormats::DigitsLower)); + USentryPlaygroundUtils::Terminate(ESentryAppTerminationType::NullPointer); } From 12544d0883aa8a2c3c863c93b8b8c07306e6ca03 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 10:52:08 +0300 Subject: [PATCH 16/20] Update SentryPlaygroundGameInstance.cpp --- 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 5caeed55f..2104e00be 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -81,7 +81,7 @@ 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 - SentrySubsystem->SetTag(TEXT("test.crash_id"), FGuid::NewGuid().ToString(EGuidFormats::DigitsLower)); + SentrySubsystem->SetTag(TEXT("test.crash_id"), FGuid::NewGuid().ToString(EGuidFormats::Digits)); USentryPlaygroundUtils::Terminate(ESentryAppTerminationType::NullPointer); } From 28c5bb6e83c7f6b6fb081bc6f44ab10aeba8156a Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 11:19:31 +0300 Subject: [PATCH 17/20] Remove integration-test param --- sample/README.md | 8 ++++---- .../SentryPlaygroundGameInstance.cpp | 12 +++++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/sample/README.md b/sample/README.md index a34176f8f..57fbc72c4 100644 --- a/sample/README.md +++ b/sample/README.md @@ -66,17 +66,17 @@ To run automation tests, several engine plugins are enabled (see `Settings -> Pl ## Integration Tests -The `SentryPlaygroundGameInstance.cpp` file contains logic that parses command line input used to launch the sample game build and runs test actions accordingly (e.g., trigger crash, capture message). Here are example commands: +The `SentryPlaygroundGameInstance.cpp` file contains logic that parses command line input used to launch the sample game build and runs test actions accordingly. Here are example commands: ```pwsh # Windows - Crash capture test -SentryPlayground.exe -nullrhi -unattended -log -integration-test -crash-capture -dsn="your-dsn-here" +SentryPlayground.exe -nullrhi -unattended -log -crash-capture -dsn="your-dsn-here" # Windows - Message capture test -SentryPlayground.exe -nullrhi -unattended -log -integration-test -message-capture +SentryPlayground.exe -nullrhi -unattended -log -message-capture ``` -To run integration tests, ensure the `-integration-test` argument is passed to the executable and specify which test to run with the following one. The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. +To run integration tests, specify which test to run using the appropriate argument (e.g., `-crash-capture` or `-message-capture`). The game will close after the test is completed. Otherwise, the game will launch as usual and present the sample UI. Optionally, you can override the DSN for integration tests by adding `-dsn="your-dsn-here"` to the command line. When provided, this DSN will be used instead of the one configured in the project settings. diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 2104e00be..fff98ccbd 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -17,9 +17,10 @@ void USentryPlaygroundGameInstance::Init() const TCHAR* CommandLine = FCommandLine::Get(); - // Check '-integration-test' commandline argument to decide between running integration tests + // Check for expected test parameters to decide between running integration tests // or launching the sample app with UI for manual testing - if (FParse::Param(FCommandLine::Get(), TEXT("integration-test"))) + if (FParse::Param(FCommandLine::Get(), TEXT("crash-capture")) || + FParse::Param(FCommandLine::Get(), TEXT("message-capture"))) { RunIntegrationTest(CommandLine); } @@ -81,7 +82,12 @@ 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 - SentrySubsystem->SetTag(TEXT("test.crash_id"), FGuid::NewGuid().ToString(EGuidFormats::Digits)); + + FString EventId = FGuid::NewGuid().ToString(EGuidFormats::Digits); + + UE_LOG(LogSentrySample, Log, TEXT("EVENT_CAPTURED: %s\n"), *EventId); + + SentrySubsystem->SetTag(TEXT("test.crash_id"), EventId); USentryPlaygroundUtils::Terminate(ESentryAppTerminationType::NullPointer); } From cd08ce4c8a99ae6d543d50fbd67cf07188fd5b1d Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 13:25:43 +0300 Subject: [PATCH 18/20] Try windows-2022 --- .github/workflows/test-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index d6a0c5cb6..82b571547 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -11,7 +11,7 @@ env: jobs: test: name: Test - runs-on: windows-latest + runs-on: windows-2022 steps: - name: Log in to GitHub package registry From 315f154fbdc7cd62fb9caa1b4751dcee6593d9b8 Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 14:09:15 +0300 Subject: [PATCH 19/20] Fix string literals --- 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 fff98ccbd..84a272528 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -100,7 +100,7 @@ void USentryPlaygroundGameInstance::RunMessageTest() UE_LOG(LogSentrySample, Log, TEXT("EVENT_CAPTURED: %s\n"), *EventId); - CompleteTestWithResult("message-capture", !EventId.IsEmpty(), "Test complete"); + CompleteTestWithResult(TEXT("message-capture"), !EventId.IsEmpty(), TEXT("Test complete")); } void USentryPlaygroundGameInstance::ConfigureTestContext() From a29147137dc285850297b66ae6968b548f22b48b Mon Sep 17 00:00:00 2001 From: Ivan Tustanivskyi Date: Thu, 4 Sep 2025 14:15:23 +0300 Subject: [PATCH 20/20] Remove unreachable code block --- .../Source/SentryPlayground/SentryPlaygroundGameInstance.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp index 84a272528..63c28023c 100644 --- a/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp +++ b/sample/Source/SentryPlayground/SentryPlaygroundGameInstance.cpp @@ -69,11 +69,6 @@ void USentryPlaygroundGameInstance::RunIntegrationTest(const TCHAR* CommandLine) { RunMessageTest(); } - else - { - // Integration test requested but no action specified - CompleteTestWithResult(TEXT("invalid-command"), false, TEXT("Missing command")); - } } void USentryPlaygroundGameInstance::RunCrashTest()