diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40dd39dc1..456c261a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,7 +15,7 @@
**Migration**: Update your `using` directives from `using Sentry;` to `using Sentry.Unity;`. IDEs like Rider can automatically
import the missing references. In some cases, you may need both `using Sentry.Unity;` (for the static API) and `using Sentry;`
(for types like `SentryId`). No changes are required to your actual SDK method calls (e.g., `SentrySdk.CaptureException()`
- remains the same). ([#2227](https://github.com/getsentry/sentry-unity/pull/2227))
+ remains the same). ([#2227](https://github.com/getsentry/sentry-unity/pull/2227), [#2239](https://github.com/getsentry/sentry-unity/pull/2239))
### Features
diff --git a/src/Sentry.Unity/Il2CppEventProcessor.cs b/src/Sentry.Unity/Il2CppEventProcessor.cs
index 68247ef77..00886084b 100644
--- a/src/Sentry.Unity/Il2CppEventProcessor.cs
+++ b/src/Sentry.Unity/Il2CppEventProcessor.cs
@@ -21,6 +21,7 @@ public UnityIl2CppEventExceptionProcessor(SentryUnityOptions options)
{
Options = options;
UnityInfo = options.UnityInfo;
+ // We're throwing here but this should never happen. We're validating UnityInfo before adding the processor.
_il2CppMethods = UnityInfo.Il2CppMethods ?? throw new ArgumentNullException(nameof(UnityInfo.Il2CppMethods),
"Unity IL2CPP methods are not available.");
diff --git a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs
index c2fe884d3..2eefd17e9 100644
--- a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs
+++ b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs
@@ -115,28 +115,31 @@ public static string GetConfigPath(string? notDefaultConfigName = null)
[field: SerializeField] public SentryLevel DiagnosticLevel { get; set; } = SentryLevel.Warning;
///
- /// Loads the ScriptableSentryUnityOptions from `Resource`.
+ /// Loads the ScriptableSentryUnityOptions from Resource.
///
- /// The SentryUnityOptions generated from the ScriptableSentryUnityOptions
+ /// The SentryUnityOptions generated from the ScriptableSentryUnityOptions
///
- /// Used for loading the SentryUnityOptions from the ScriptableSentryUnityOptions during runtime.
+ /// This gets called from SentryInitialization during the game's startup.
///
public static SentryUnityOptions? LoadSentryUnityOptions()
{
var scriptableOptions = Resources.Load($"{ConfigRootFolder}/{ConfigName}");
if (scriptableOptions is not null)
{
- return scriptableOptions.ToSentryUnityOptions(false);
+ return scriptableOptions.ToSentryUnityOptions();
}
return null;
}
- internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityInfo? unityInfo = null, IApplication? application = null)
+ internal SentryUnityOptions ToSentryUnityOptions(
+ ISentryUnityInfo? unityInfo = null,
+ IApplication? application = null,
+ bool isBuilding = false)
{
application ??= ApplicationAdapter.Instance;
- var options = new SentryUnityOptions(isBuilding, application, unityInfo)
+ var options = new SentryUnityOptions(unityInfo, application, isBuilding: isBuilding)
{
Enabled = Enabled,
Dsn = Dsn,
@@ -186,6 +189,12 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn
PerformanceAutoInstrumentationEnabled = AutoAwakeTraces,
};
+ // By default, the cacheDirectoryPath gets set on known platforms. We're overwriting this behaviour here.
+ if (!EnableOfflineCaching)
+ {
+ options.CacheDirectoryPath = null;
+ }
+
if (!string.IsNullOrWhiteSpace(ReleaseOverride))
{
options.Release = ReleaseOverride;
@@ -227,23 +236,11 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn
// Without setting up here we might miss out on logs between option-loading (now) and Init - i.e. native configuration
options.SetupUnityLogging();
- if (options.AttachViewHierarchy)
- {
- options.AddEventProcessor(new ViewHierarchyEventProcessor(options));
- }
- if (options.AttachScreenshot)
- {
- options.AddEventProcessor(new ScreenshotEventProcessor(options));
- }
-
- if (!application.IsEditor && options.Il2CppLineNumberSupportEnabled && unityInfo?.Il2CppMethods != null)
- {
- options.AddIl2CppExceptionProcessor();
- }
-
- HandlePlatformRestrictedOptions(options, application);
+ // ExceptionFilters are added by default to the options.
HandleExceptionFilter(options);
+ // The AnrDetectionIntegration is added by default. Since it is a ScriptableUnityOptions-only property we have to
+ // remove the integration when creating the options through here
if (!AnrDetectionEnabled)
{
options.DisableAnrIntegration();
@@ -252,41 +249,6 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn
return options;
}
- internal void HandlePlatformRestrictedOptions(SentryUnityOptions options, IApplication application)
- {
- if (!options.UnityInfo.IsKnownPlatform())
- {
- options.DisableFileWrite = true;
-
- // This is only provided on a best-effort basis for other than the explicitly supported platforms.
- if (options.BackgroundWorker is null)
- {
- options.DiagnosticLogger?.LogDebug("Platform support for background thread execution is unknown: using WebBackgroundWorker.");
- options.BackgroundWorker = new WebBackgroundWorker(options, SentryMonoBehaviour.Instance);
- }
-
- // Disable offline caching regardless whether it was enabled or not.
- options.CacheDirectoryPath = null;
- if (EnableOfflineCaching)
- {
- options.DiagnosticLogger?.LogDebug("Platform support for offline caching is unknown: disabling.");
- }
-
- // Requires file access, see https://github.com/getsentry/sentry-unity/issues/290#issuecomment-1163608988
- if (options.AutoSessionTracking)
- {
- options.DiagnosticLogger?.LogDebug("Platform support for automatic session tracking is unknown: disabling.");
- options.AutoSessionTracking = false;
- }
-
- return;
- }
-
- // Only assign the cache directory path if we're on a "known" platform. Accessing `Application.persistentDataPath`
- // implicitly creates a directory and leads to crashes i.e. on the Switch.
- options.CacheDirectoryPath = EnableOfflineCaching ? application.PersistentDataPath : null;
- }
-
private void HandleExceptionFilter(SentryUnityOptions options)
{
if (!options.FilterBadGatewayExceptions)
diff --git a/src/Sentry.Unity/SentryUnityOptions.cs b/src/Sentry.Unity/SentryUnityOptions.cs
index 0aba6aa4a..34144e7cc 100644
--- a/src/Sentry.Unity/SentryUnityOptions.cs
+++ b/src/Sentry.Unity/SentryUnityOptions.cs
@@ -298,14 +298,14 @@ internal string? DefaultUserId
internal ISentryUnityInfo UnityInfo { get; private set; }
internal Action? PlatformConfiguration { get; private set; }
- public SentryUnityOptions() : this(false, ApplicationAdapter.Instance) { }
-
- internal SentryUnityOptions(bool isBuilding, IApplication application, ISentryUnityInfo? unityInfo = null) :
- this(SentryMonoBehaviour.Instance, application, isBuilding, unityInfo)
- { }
+ public SentryUnityOptions() : this(isBuilding: false) { }
// For testing
- internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication application, bool isBuilding, ISentryUnityInfo? unityInfo = null)
+ internal SentryUnityOptions(
+ ISentryUnityInfo? unityInfo = null,
+ IApplication? application = null,
+ SentryMonoBehaviour? behaviour = null,
+ bool isBuilding = false)
{
// NOTE: 'SentryPlatformServices.UnityInfo' throws when the UnityInfo has not been set. This should not happen.
// The PlatformServices are set through the RuntimeLoad attribute in 'SentryInitialization.cs' and are required
@@ -313,30 +313,33 @@ internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication applicat
UnityInfo = unityInfo ?? SentryPlatformServices.UnityInfo;
PlatformConfiguration = SentryPlatformServices.PlatformConfiguration;
+ application ??= ApplicationAdapter.Instance;
+ behaviour ??= SentryMonoBehaviour.Instance;
+
// IL2CPP doesn't support Process.GetCurrentProcess().StartupTime
DetectStartupTime = StartupTimeDetectionMode.Fast;
- this.AddInAppExclude("UnityEngine");
- this.AddInAppExclude("UnityEditor");
+ AddInAppExclude("UnityEngine");
+ AddInAppExclude("UnityEditor");
var processor = new UnityEventProcessor(this);
- this.AddEventProcessor(processor);
- this.AddTransactionProcessor(processor);
- this.AddExceptionProcessor(new UnityExceptionProcessor());
-
- this.AddIntegration(new UnityLogHandlerIntegration(this));
- this.AddIntegration(new UnityApplicationLoggingIntegration());
- this.AddIntegration(new StartupTracingIntegration());
- this.AddIntegration(new AnrIntegration(behaviour));
- this.AddIntegration(new UnityScopeIntegration(application, unityInfo));
- this.AddIntegration(new UnityBeforeSceneLoadIntegration());
- this.AddIntegration(new SceneManagerIntegration());
- this.AddIntegration(new SceneManagerTracingIntegration());
- this.AddIntegration(new SessionIntegration(behaviour));
- this.AddIntegration(new TraceGenerationIntegration(behaviour));
-
- this.AddExceptionFilter(new UnityBadGatewayExceptionFilter());
- this.AddExceptionFilter(new UnityWebExceptionFilter());
- this.AddExceptionFilter(new UnitySocketExceptionFilter());
+ AddEventProcessor(processor);
+ AddTransactionProcessor(processor);
+ AddExceptionProcessor(new UnityExceptionProcessor());
+
+ AddIntegration(new UnityLogHandlerIntegration(this));
+ AddIntegration(new UnityApplicationLoggingIntegration());
+ AddIntegration(new StartupTracingIntegration());
+ AddIntegration(new AnrIntegration(behaviour));
+ AddIntegration(new UnityScopeIntegration(application, unityInfo));
+ AddIntegration(new UnityBeforeSceneLoadIntegration());
+ AddIntegration(new SceneManagerIntegration());
+ AddIntegration(new SceneManagerTracingIntegration());
+ AddIntegration(new SessionIntegration(behaviour));
+ AddIntegration(new TraceGenerationIntegration(behaviour));
+
+ AddExceptionFilter(new UnityBadGatewayExceptionFilter());
+ AddExceptionFilter(new UnityWebExceptionFilter());
+ AddExceptionFilter(new UnitySocketExceptionFilter());
IsGlobalModeEnabled = true;
@@ -373,6 +376,13 @@ internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication applicat
{ LogType.Error, true},
{ LogType.Exception, true},
};
+
+ // Only assign the cache directory path if we're on a "known" platform. Accessing `Application.persistentDataPath`
+ // implicitly creates a directory and leads to crashes i.e. on the Switch.
+ if (unityInfo?.IsKnownPlatform() ?? false)
+ {
+ CacheDirectoryPath = application.PersistentDataPath;
+ }
}
public override string ToString()
diff --git a/src/Sentry.Unity/SentryUnityOptionsExtensions.cs b/src/Sentry.Unity/SentryUnityOptionsExtensions.cs
index ea97618f5..6793e0116 100644
--- a/src/Sentry.Unity/SentryUnityOptionsExtensions.cs
+++ b/src/Sentry.Unity/SentryUnityOptionsExtensions.cs
@@ -63,11 +63,6 @@ internal static void SetupUnityLogging(this SentryUnityOptions options)
}
}
- internal static void AddIl2CppExceptionProcessor(this SentryUnityOptions options)
- {
- options.AddExceptionProcessor(new UnityIl2CppEventExceptionProcessor(options));
- }
-
///
/// Disables the capture of errors through .
///
diff --git a/src/Sentry.Unity/SentryUnitySdk.cs b/src/Sentry.Unity/SentryUnitySdk.cs
index 052139275..c590cbbda 100644
--- a/src/Sentry.Unity/SentryUnitySdk.cs
+++ b/src/Sentry.Unity/SentryUnitySdk.cs
@@ -11,7 +11,7 @@ internal class SentryUnitySdk
{
private readonly SentryUnityOptions _options;
private IDisposable _dotnetSdk = null!;
- private FileStream? _lockFile;
+ private FileStream? LockFile;
private SentryUnitySdk(SentryUnityOptions options)
{
@@ -30,30 +30,14 @@ private SentryUnitySdk(SentryUnityOptions options)
MainThreadData.CollectData();
- // On Standalone, we disable cache dir in case multiple app instances run over the same path.
- // Note: we cannot use a named Mutex, because Unit doesn't support it. Instead, we create a file with `FileShare.None`.
- // https://forum.unity.com/threads/unsupported-internal-call-for-il2cpp-mutex-createmutex_internal-named-mutexes-are-not-supported.387334/
- if (ApplicationAdapter.Instance.Platform is RuntimePlatform.WindowsPlayer && options.CacheDirectoryPath is not null)
- {
- try
- {
- unitySdk._lockFile = new FileStream(Path.Combine(options.CacheDirectoryPath, "sentry-unity.lock"), FileMode.OpenOrCreate,
- FileAccess.ReadWrite, FileShare.None);
- }
- catch (Exception ex)
- {
- options.DiagnosticLogger?.LogWarning("An exception was thrown while trying to " +
- "acquire a lockfile on the config directory: .NET event cache will be disabled.", ex);
- options.CacheDirectoryPath = null;
- options.AutoSessionTracking = false;
- }
- }
+ // Some integrations are controlled through a flag and opt-in. Adding these integrations late so we have equal
+ // behaviour whether the options got created through the ScriptableObject or the SDK gets manually initialized
+ AddIntegrations(options);
+ SetUpWindowsPlayerCaching(unitySdk, options);
- unitySdk._dotnetSdk = Sentry.SentrySdk.Init(options);
+ ConfigureUnsupportedPlatformFallbacks(options);
- // We can safely call this during initialization. If the SDK self-initialized we're right on time. If the SDK
- // was initialized manually, the RuntimeOnLoad attributes already triggered, making this call a no-op.
- StartupTracingIntegration.StartTracing();
+ unitySdk._dotnetSdk = Sentry.SentrySdk.Init(options);
// We can safely call this during initialization. If the SDK self-initialized we're right on time. If the SDK
// was initialized manually, the RuntimeOnLoad attributes already triggered, making this call a no-op.
@@ -99,7 +83,7 @@ public void Close()
try
{
// We don't really need to close, Windows would release the lock anyway, but let's be nice.
- _lockFile?.Close();
+ LockFile?.Close();
}
catch (Exception ex)
{
@@ -141,4 +125,77 @@ public void CaptureFeedback(string message, string? email, string? name, bool ad
Sentry.SentrySdk.CurrentHub.CaptureFeedback(message, email, name, hint: hint);
}
+
+ internal static void SetUpWindowsPlayerCaching(SentryUnitySdk unitySdk, SentryUnityOptions options)
+ {
+ // On Windows-Standalone, we disable cache dir in case multiple app instances run over the same path.
+ // Note: we cannot use a named Mutex, because Unity doesn't support it. Instead, we create a file with `FileShare.None`.
+ // https://forum.unity.com/threads/unsupported-internal-call-for-il2cpp-mutex-createmutex_internal-named-mutexes-are-not-supported.387334/
+ if (ApplicationAdapter.Instance.Platform is not RuntimePlatform.WindowsPlayer ||
+ options.CacheDirectoryPath is null)
+ {
+ return;
+ }
+
+ try
+ {
+ unitySdk.LockFile = new FileStream(Path.Combine(options.CacheDirectoryPath, "sentry-unity.lock"), FileMode.OpenOrCreate,
+ FileAccess.ReadWrite, FileShare.None);
+ }
+ catch (Exception ex)
+ {
+ options.DiagnosticLogger?.LogWarning("An exception was thrown while trying to " +
+ "acquire a lockfile on the config directory: .NET event cache will be disabled.", ex);
+ options.CacheDirectoryPath = null;
+ options.AutoSessionTracking = false;
+ }
+ }
+
+ internal static void AddIntegrations(SentryUnityOptions options)
+ {
+ if (options.AttachViewHierarchy)
+ {
+ options.AddEventProcessor(new ViewHierarchyEventProcessor(options));
+ }
+ if (options.AttachScreenshot)
+ {
+ options.AddEventProcessor(new ScreenshotEventProcessor(options));
+ }
+
+ if (!ApplicationAdapter.Instance.IsEditor &&
+ options.UnityInfo.IL2CPP &&
+ options.Il2CppLineNumberSupportEnabled)
+ {
+ if (options.UnityInfo.Il2CppMethods is not null)
+ {
+ options.AddExceptionProcessor(new UnityIl2CppEventExceptionProcessor(options));
+ }
+ else
+ {
+ options.DiagnosticLogger?.LogWarning("Failed to find required IL2CPP methods - Skipping line number support");
+ }
+ }
+ }
+
+ internal static void ConfigureUnsupportedPlatformFallbacks(SentryUnityOptions options)
+ {
+ if (!options.UnityInfo.IsKnownPlatform())
+ {
+ options.DisableFileWrite = true;
+
+ // Requires file access, see https://github.com/getsentry/sentry-unity/issues/290#issuecomment-1163608988
+ if (options.AutoSessionTracking)
+ {
+ options.DiagnosticLogger?.LogDebug("Platform support for automatic session tracking is unknown: disabling.");
+ options.AutoSessionTracking = false;
+ }
+
+ // This is only provided on a best-effort basis for other than the explicitly supported platforms.
+ if (options.BackgroundWorker is null)
+ {
+ options.DiagnosticLogger?.LogDebug("Platform support for background thread execution is unknown: using WebBackgroundWorker.");
+ options.BackgroundWorker = new WebBackgroundWorker(options, SentryMonoBehaviour.Instance);
+ }
+ }
+ }
}
diff --git a/test/Sentry.Unity.Android.Tests/SentryNativeAndroidTests.cs b/test/Sentry.Unity.Android.Tests/SentryNativeAndroidTests.cs
index ab485b68b..1496407f9 100644
--- a/test/Sentry.Unity.Android.Tests/SentryNativeAndroidTests.cs
+++ b/test/Sentry.Unity.Android.Tests/SentryNativeAndroidTests.cs
@@ -41,7 +41,7 @@ public void TearDown() =>
[Test]
public void Configure_DefaultConfiguration_SetsScopeObserver()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
SentryNativeAndroid.Configure(options);
@@ -51,7 +51,7 @@ public void Configure_DefaultConfiguration_SetsScopeObserver()
[Test]
public void Configure_DefaultConfiguration_SetsCrashedLastRun()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
SentryNativeAndroid.Configure(options);
@@ -61,7 +61,7 @@ public void Configure_DefaultConfiguration_SetsCrashedLastRun()
[Test]
public void Configure_NativeAndroidSupportDisabled_ObserverIsNull()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
options.AndroidNativeSupportEnabled = false;
SentryNativeAndroid.Configure(options);
@@ -72,7 +72,7 @@ public void Configure_NativeAndroidSupportDisabled_ObserverIsNull()
[Test]
public void Configure_DefaultConfiguration_EnablesScopeSync()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
SentryNativeAndroid.Configure(options);
@@ -82,7 +82,7 @@ public void Configure_DefaultConfiguration_EnablesScopeSync()
[Test]
public void Configure_NativeAndroidSupportDisabled_DisabledScopeSync()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
options.AndroidNativeSupportEnabled = false;
SentryNativeAndroid.Configure(options);
@@ -96,7 +96,7 @@ public void Configure_NativeAndroidSupportDisabled_DisabledScopeSync()
public void Configure_IL2CPP_ReInitializesNativeBackend(bool il2cpp, bool expectedReinstall)
{
_sentryUnityInfo.IL2CPP = il2cpp;
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
Assert.False(_reinstallCalled); // Sanity check
@@ -108,7 +108,7 @@ public void Configure_IL2CPP_ReInitializesNativeBackend(bool il2cpp, bool expect
[Test]
public void Configure_NativeAndroidSupportDisabled_DoesNotReInitializeNativeBackend()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
options.AndroidNativeSupportEnabled = false;
SentryNativeAndroid.Configure(options);
@@ -119,7 +119,7 @@ public void Configure_NativeAndroidSupportDisabled_DoesNotReInitializeNativeBack
[Test]
public void Configure_NoInstallationIdReturned_SetsNewDefaultUserId()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo);
+ var options = new SentryUnityOptions(_sentryUnityInfo);
_testSentryJava.InstallationId = string.Empty;
SentryNativeAndroid.Configure(options);
@@ -130,7 +130,7 @@ public void Configure_NoInstallationIdReturned_SetsNewDefaultUserId()
[Test]
public void Configure_DefaultConfigurationSentryJavaNotPresent_LogsErrorAndReturns()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo)
+ var options = new SentryUnityOptions(_sentryUnityInfo)
{
Debug = true,
DiagnosticLevel = SentryLevel.Debug,
@@ -150,7 +150,7 @@ public void Configure_DefaultConfigurationSentryJavaNotPresent_LogsErrorAndRetur
[Test]
public void Configure_NativeAlreadyInitialized_LogsAndConfigures()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo)
+ var options = new SentryUnityOptions(_sentryUnityInfo)
{
Debug = true,
DiagnosticLevel = SentryLevel.Debug,
@@ -171,7 +171,7 @@ public void Configure_NativeAlreadyInitialized_LogsAndConfigures()
[Test]
public void Configure_NativeInitFails_LogsErrorAndReturns()
{
- var options = new SentryUnityOptions(false, new TestApplication(), _sentryUnityInfo)
+ var options = new SentryUnityOptions(_sentryUnityInfo)
{
Debug = true,
DiagnosticLevel = SentryLevel.Debug,
diff --git a/test/Sentry.Unity.Tests/ContextWriterTests.cs b/test/Sentry.Unity.Tests/ContextWriterTests.cs
index b432c5ea0..eca1dd663 100644
--- a/test/Sentry.Unity.Tests/ContextWriterTests.cs
+++ b/test/Sentry.Unity.Tests/ContextWriterTests.cs
@@ -66,7 +66,7 @@ public void Arguments()
};
var context = new MockContextWriter();
- var options = new SentryUnityOptions(_sentryMonoBehaviour, _testApplication, false)
+ var options = new SentryUnityOptions(application: _testApplication, behaviour: _sentryMonoBehaviour)
{
Dsn = "http://publickey@localhost/12345",
Enabled = true,
diff --git a/test/Sentry.Unity.Tests/ScriptableSentryUnityOptionsTests.cs b/test/Sentry.Unity.Tests/ScriptableSentryUnityOptionsTests.cs
index d0ecaf59e..e858ae8cc 100644
--- a/test/Sentry.Unity.Tests/ScriptableSentryUnityOptionsTests.cs
+++ b/test/Sentry.Unity.Tests/ScriptableSentryUnityOptionsTests.cs
@@ -94,7 +94,7 @@ public void ToSentryUnityOptions_ValueMapping_AreEqual(bool isBuilding, bool ena
scriptableOptions.DebugOnlyInEditor = false; // Affects Debug otherwise
scriptableOptions.DiagnosticLevel = expectedOptions.DiagnosticLevel;
- var optionsActual = scriptableOptions.ToSentryUnityOptions(isBuilding, _fixture.UnityInfo, _fixture.Application);
+ var optionsActual = scriptableOptions.ToSentryUnityOptions(_fixture.UnityInfo, _fixture.Application, isBuilding);
AssertOptions(expectedOptions, optionsActual);
}
@@ -122,30 +122,18 @@ public void ToSentryUnityOptions_HasOptionsConfiguration_GetsCalled(bool isBuild
var scriptableOptions = ScriptableObject.CreateInstance();
scriptableOptions.RuntimeOptionsConfiguration = optionsConfiguration;
- scriptableOptions.ToSentryUnityOptions(isBuilding, _fixture.UnityInfo);
+ scriptableOptions.ToSentryUnityOptions(_fixture.UnityInfo, isBuilding: isBuilding);
Assert.AreEqual(optionsConfiguration.GotCalled, !isBuilding);
}
- [Test]
- public void ToSentryUnityOptions_UnknownPlatforms_DoesNotAccessDisk()
- {
- var scriptableOptions = ScriptableObject.CreateInstance();
- _fixture.UnityInfo = new TestUnityInfo(false);
-
- var options = scriptableOptions.ToSentryUnityOptions(false, _fixture.UnityInfo, _fixture.Application);
-
- Assert.IsNull(options.CacheDirectoryPath);
- Assert.IsFalse(options.AutoSessionTracking);
- }
-
[Test]
public void ToSentryUnityOptions_WebExceptionFilterAdded()
{
var scriptableOptions = ScriptableObject.CreateInstance();
_fixture.UnityInfo = new TestUnityInfo(true);
- var options = scriptableOptions.ToSentryUnityOptions(false, _fixture.UnityInfo, _fixture.Application);
+ var options = scriptableOptions.ToSentryUnityOptions(_fixture.UnityInfo, _fixture.Application);
var exceptionFiltersPropertyInfo = typeof(SentryOptions).GetProperty("ExceptionFilters", BindingFlags.NonPublic | BindingFlags.Instance);
var filters = exceptionFiltersPropertyInfo.GetValue(options) as List;
@@ -158,7 +146,7 @@ public void ToSentryUnityOptions_UnitySocketExceptionFilterAdded()
var scriptableOptions = ScriptableObject.CreateInstance();
_fixture.UnityInfo = new TestUnityInfo(true);
- var options = scriptableOptions.ToSentryUnityOptions(false, _fixture.UnityInfo, _fixture.Application);
+ var options = scriptableOptions.ToSentryUnityOptions(_fixture.UnityInfo, _fixture.Application);
var exceptionFiltersPropertyInfo = typeof(SentryOptions).GetProperty("ExceptionFilters", BindingFlags.NonPublic | BindingFlags.Instance);
var filters = exceptionFiltersPropertyInfo.GetValue(options) as List;
@@ -171,49 +159,13 @@ public void ToSentryUnityOptions_UnityBadGatewayExceptionFilterAdded()
var scriptableOptions = ScriptableObject.CreateInstance();
_fixture.UnityInfo = new TestUnityInfo(true);
- var options = scriptableOptions.ToSentryUnityOptions(false, _fixture.UnityInfo, _fixture.Application);
+ var options = scriptableOptions.ToSentryUnityOptions(_fixture.UnityInfo, _fixture.Application);
var exceptionFiltersPropertyInfo = typeof(SentryOptions).GetProperty("ExceptionFilters", BindingFlags.NonPublic | BindingFlags.Instance);
var filters = exceptionFiltersPropertyInfo.GetValue(options) as List;
Assert.True(filters.OfType().Any());
}
- [Test]
- public void HandlePlatformRestrictedOptions_UnknownPlatform_SetsRestrictedOptions()
- {
- _fixture.UnityInfo = new TestUnityInfo(false);
-
- var scriptableOptions = ScriptableObject.CreateInstance();
- scriptableOptions.EnableOfflineCaching = true;
-
- var options = new SentryUnityOptions(false, _fixture.Application, _fixture.UnityInfo)
- {
- DisableFileWrite = false,
- CacheDirectoryPath = "some/path",
- AutoSessionTracking = true
- };
-
- scriptableOptions.HandlePlatformRestrictedOptions(options, _fixture.Application);
-
- Assert.IsTrue(options.DisableFileWrite);
- Assert.IsNull(options.CacheDirectoryPath);
- Assert.IsFalse(options.AutoSessionTracking);
- Assert.IsTrue(options.BackgroundWorker is WebBackgroundWorker);
- }
-
- [Test]
- public void HandlePlatformRestrictedOptions_KnownPlatform_SetsRestrictedOptions()
- {
- var scriptableOptions = ScriptableObject.CreateInstance();
- scriptableOptions.EnableOfflineCaching = true;
-
- var options = new SentryUnityOptions(false, _fixture.Application, _fixture.UnityInfo);
-
- scriptableOptions.HandlePlatformRestrictedOptions(options, _fixture.Application);
-
- Assert.AreEqual(options.CacheDirectoryPath, _fixture.Application.PersistentDataPath);
- }
-
public static void AssertOptions(SentryUnityOptions expected, SentryUnityOptions actual)
{
Assert.AreEqual(expected.Enabled, actual.Enabled);
diff --git a/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs b/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs
index 943f45ac3..91f1a433f 100644
--- a/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs
+++ b/test/Sentry.Unity.Tests/SentryUnityOptionsTests.cs
@@ -7,6 +7,7 @@ public sealed class SentryUnityOptionsTests
{
class Fixture
{
+ public TestUnityInfo UnityInfo { get; set; } = new();
public TestApplication Application { get; set; } = new(
productName: "TestApplication",
version: "0.1.0",
@@ -14,7 +15,7 @@ class Fixture
persistentDataPath: "test/persistent/data/path");
public bool IsBuilding { get; set; }
- public SentryUnityOptions GetSut() => new SentryUnityOptions(IsBuilding, Application);
+ public SentryUnityOptions GetSut() => new(UnityInfo, Application, isBuilding: IsBuilding);
}
[SetUp]
@@ -37,7 +38,17 @@ public void Ctor_Environment_IsNull(bool isEditor, bool isBuilding, string expec
}
[Test]
- public void Ctor_CacheDirectoryPath_IsNull() => Assert.IsNull(_fixture.GetSut().CacheDirectoryPath);
+ [TestCase(true, "some/path", "some/path")]
+ [TestCase(false, "some/path", null)]
+ public void Ctor_IfPlatformIsKnown_SetsCacheDirectoryPath(bool isKnownPlatform, string applicationDataPath, string? expectedCacheDirectoryPath)
+ {
+ _fixture.UnityInfo = new TestUnityInfo(isKnownPlatform: isKnownPlatform);
+ _fixture.Application.PersistentDataPath = applicationDataPath;
+
+ var sut = _fixture.GetSut();
+
+ Assert.AreEqual(sut.CacheDirectoryPath, expectedCacheDirectoryPath);
+ }
[Test]
public void Ctor_IsGlobalModeEnabled_IsTrue() => Assert.IsTrue(_fixture.GetSut().IsGlobalModeEnabled);
diff --git a/test/Sentry.Unity.Tests/SentryUnityTests.cs b/test/Sentry.Unity.Tests/SentryUnityTests.cs
index e3326cad6..9e1dd58d5 100644
--- a/test/Sentry.Unity.Tests/SentryUnityTests.cs
+++ b/test/Sentry.Unity.Tests/SentryUnityTests.cs
@@ -6,6 +6,7 @@
using Debug = UnityEngine.Debug;
using Sentry.Extensibility;
using Sentry.Unity.Tests.SharedClasses;
+using Sentry.Unity.Tests.Stubs;
namespace Sentry.Unity.Tests;
@@ -173,4 +174,21 @@ public void GetLastRunState_WithNullDelegate_ReturnsUnknown()
// Assert
Assert.AreEqual(SentrySdk.CrashedLastRun.Unknown, result);
}
+
+ [Test]
+ public void ConfigureUnsupportedPlatformFallbacks()
+ {
+ var unityInfo = new TestUnityInfo(false);
+ var options = new SentryUnityOptions(unityInfo)
+ {
+ DisableFileWrite = false,
+ AutoSessionTracking = true
+ };
+
+ SentryUnitySdk.ConfigureUnsupportedPlatformFallbacks(options);
+
+ Assert.IsTrue(options.DisableFileWrite);
+ Assert.IsFalse(options.AutoSessionTracking);
+ Assert.IsTrue(options.BackgroundWorker is WebBackgroundWorker);
+ }
}
diff --git a/test/Sentry.Unity.Tests/UnityEventScopeTests.cs b/test/Sentry.Unity.Tests/UnityEventScopeTests.cs
index 2085e1682..17deedc88 100644
--- a/test/Sentry.Unity.Tests/UnityEventScopeTests.cs
+++ b/test/Sentry.Unity.Tests/UnityEventScopeTests.cs
@@ -113,7 +113,7 @@ public void SentrySdkCaptureEvent(bool captureOnUiThread)
RenderingThreadingMode = new Lazy(() => "MultiThreaded"),
StartTime = new(() => DateTimeOffset.UtcNow),
};
- var options = new SentryUnityOptions(_sentryMonoBehaviour, _testApplication, false, new TestUnityInfo { IL2CPP = true })
+ var options = new SentryUnityOptions(new TestUnityInfo { IL2CPP = true }, _testApplication, _sentryMonoBehaviour)
{
Dsn = "https://b8fd848b31444e80aa102e96d2a6a648@o510466.ingest.sentry.io/5606182",
Enabled = true,
diff --git a/test/Sentry.Unity.iOS.Tests/SentryNativeIosTests.cs b/test/Sentry.Unity.iOS.Tests/SentryNativeIosTests.cs
index 6bb16cc49..4e66b4bfb 100644
--- a/test/Sentry.Unity.iOS.Tests/SentryNativeIosTests.cs
+++ b/test/Sentry.Unity.iOS.Tests/SentryNativeIosTests.cs
@@ -10,7 +10,7 @@ public class SentryNativeCocoaTests
[Test]
public void Configure_DefaultConfiguration_iOS()
{
- var options = new SentryUnityOptions(false, new TestApplication(), new TestUnityInfo { IL2CPP = false });
+ var options = new SentryUnityOptions(new TestUnityInfo { IL2CPP = false });
// Note: can't test iOS - throws because it tries to call SentryCocoaBridgeProxy.Init()
// but the bridge isn't loaded now...
@@ -22,7 +22,7 @@ public void Configure_DefaultConfiguration_iOS()
public void Configure_NativeSupportDisabled_iOS()
{
var unityInfo = new TestUnityInfo(true, false, false) { IL2CPP = false };
- var options = new SentryUnityOptions(false, new TestApplication(), unityInfo) { IosNativeSupportEnabled = false };
+ var options = new SentryUnityOptions(unityInfo) { IosNativeSupportEnabled = false };
SentryNativeCocoa.Configure(options, RuntimePlatform.IPhonePlayer);
Assert.Null(options.ScopeObserver);
Assert.Null(options.CrashedLastRun);
@@ -32,7 +32,7 @@ public void Configure_NativeSupportDisabled_iOS()
[Test]
public void Configure_DefaultConfiguration_macOS()
{
- var options = new SentryUnityOptions(false, new TestApplication(), new TestUnityInfo { IL2CPP = false });
+ var options = new SentryUnityOptions(new TestUnityInfo { IL2CPP = false });
// Note: can't test macOS - throws because it tries to call SentryCocoaBridgeProxy.Init()
// but the bridge isn't loaded now...
Assert.Throws(() =>
@@ -43,7 +43,7 @@ public void Configure_DefaultConfiguration_macOS()
public void Configure_NativeSupportDisabled_macOS()
{
var unityInfo = new TestUnityInfo(true, false, false) { IL2CPP = false };
- var options = new SentryUnityOptions(false, new TestApplication(), unityInfo) { MacosNativeSupportEnabled = false };
+ var options = new SentryUnityOptions(unityInfo) { MacosNativeSupportEnabled = false };
SentryNativeCocoa.Configure(options, RuntimePlatform.OSXPlayer);
Assert.Null(options.ScopeObserver);
Assert.Null(options.CrashedLastRun);
diff --git a/test/SharedClasses/TestApplication.cs b/test/SharedClasses/TestApplication.cs
index d41a46826..c8551297d 100644
--- a/test/SharedClasses/TestApplication.cs
+++ b/test/SharedClasses/TestApplication.cs
@@ -32,7 +32,7 @@ public TestApplication(
public string Version { get; }
public string BuildGUID { get; }
public string UnityVersion { get; set; }
- public string PersistentDataPath { get; }
+ public string PersistentDataPath { get; set; }
public RuntimePlatform Platform { get; set; }
private void OnQuitting() => Quitting?.Invoke();