Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

### Fixes

- The SDK now deduplicates trace generation during startup and scene loading ([#2301](https://github.com/getsentry/sentry-unity/pull/2301))
- The SDK now automatically picks up previously missing debug symbols - i.e. `BurstDebugInformation`, by passing the
target directory path to Sentry CLI. Sentry CLI then automatically and recursively picks up any not yet uploaded symbols. ([#2298](https://github.com/getsentry/sentry-unity/pull/2298))
- The check used to verify whether the current thread is the main-thread now includes `JobsUtility.IsExecutingJob` to support running in Burst. ([#2226](https://github.com/getsentry/sentry-unity/pull/2226))
Expand Down
38 changes: 27 additions & 11 deletions src/Sentry.Unity/Integrations/TraceGenerationIntegration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

namespace Sentry.Unity.Integrations;

/// <summary>
/// The TraceGenerationIntegration is used in case of
/// </summary>
internal sealed class TraceGenerationIntegration : ISdkIntegration
{
private readonly ISceneManager _sceneManager;
Expand All @@ -19,21 +22,34 @@ internal TraceGenerationIntegration(ISentryMonoBehaviour sentryMonoBehaviour, IS

public void Register(IHub hub, SentryOptions options)
{
hub.ConfigureScope(UpdatePropagationContext);

_sentryMonoBehaviour.ApplicationResuming += () =>
{
options.DiagnosticLogger?.LogDebug("Application resumed. Creating new Trace.");
hub.ConfigureScope(UpdatePropagationContext);
options.DiagnosticLogger?.LogDebug("Game resuming. Creating new Trace.");
hub.ConfigureScope(scope => scope.SetPropagationContext(new SentryPropagationContext()));;
};

_sceneManager.ActiveSceneChanged += (_, _) =>
if (options is not SentryUnityOptions unityOptions)
{
options.DiagnosticLogger?.LogDebug("Active Scene changed. Creating new Trace.");
hub.ConfigureScope(UpdatePropagationContext);
};
}
return;
}

var isTracingEnabled = unityOptions.TracesSampleRate > 0.0f;

private static void UpdatePropagationContext(Scope scope) =>
scope.SetPropagationContext(new SentryPropagationContext());
// Create initial trace context if tracing is disabled or startup tracing is disabled
if (!isTracingEnabled || !unityOptions.AutoStartupTraces)
{
options.DiagnosticLogger?.LogDebug("Startup. Creating new Trace.");
hub.ConfigureScope(scope => scope.SetPropagationContext(new SentryPropagationContext()));
}

// Set up scene change handling if tracing is disabled or auto scene load traces are disabled
if (!isTracingEnabled || !unityOptions.AutoSceneLoadTraces)
{
_sceneManager.ActiveSceneChanged += (_, _) =>
{
options.DiagnosticLogger?.LogDebug("Active Scene changed. Creating new Trace.");
hub.ConfigureScope(scope => scope.SetPropagationContext(new SentryPropagationContext()));
};
}
}
}
60 changes: 49 additions & 11 deletions test/Sentry.Unity.Tests/TraceGenerationIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ private class Fixture
public TestSentryMonoBehaviour SentryMonoBehaviour { get; set; } = new();
public TestHub TestHub { get; set; } = new();
public TestLogger Logger { get; set; } = new();
public SentryOptions SentryOptions { get; set; }
public SentryUnityOptions SentryOptions { get; set; }

public Fixture() => SentryOptions = new SentryOptions { DiagnosticLogger = Logger };
public Fixture() => SentryOptions = new SentryUnityOptions { DiagnosticLogger = Logger };

public TraceGenerationIntegration GetSut() => new(SentryMonoBehaviour, SceneManager);
}
Expand All @@ -32,10 +32,14 @@ public void SetUp()
Sentry.SentrySdk.UseHub(_fixture.TestHub);
}

[Test]
public void TraceGeneration_OnRegister_GeneratesInitialTrace()
[TestCase(0.0f, false)]
[TestCase(0.0f, true)]
[TestCase(1.0f, false)]
public void Register_TracingDisabledOrAutoStartupTracesDisabled_GeneratesInitialTrace(float tracesSampleRate, bool autoStartupTraces)
{
// Arrange
_fixture.SentryOptions.TracesSampleRate = tracesSampleRate;
_fixture.SentryOptions.AutoStartupTraces = autoStartupTraces;
var sut = _fixture.GetSut();

// Act
Expand All @@ -46,12 +50,26 @@ public void TraceGeneration_OnRegister_GeneratesInitialTrace()
var scope = new Scope(_fixture.SentryOptions);
var initialPropagationContext = scope.PropagationContext;
configureScope(scope);

Assert.AreNotEqual(initialPropagationContext, scope.PropagationContext);
}

[Test]
public void TraceGeneration_OnApplicationResume_GeneratesNewTrace()
public void Register_TracingEnabledAndAutoStartupTracesEnabled_DoesNotGenerateInitialTrace()
{
// Arrange
_fixture.SentryOptions.TracesSampleRate = 1.0f;
_fixture.SentryOptions.AutoStartupTraces = true;
var sut = _fixture.GetSut();

// Act
sut.Register(_fixture.TestHub, _fixture.SentryOptions);

// Assert
Assert.IsEmpty(_fixture.TestHub.ConfigureScopeCalls);
}

[Test]
public void ApplicationResuming_WhenCalled_GeneratesNewTrace()
{
// Arrange
var sut = _fixture.GetSut();
Expand All @@ -62,7 +80,6 @@ public void TraceGeneration_OnApplicationResume_GeneratesNewTrace()
_fixture.SentryMonoBehaviour.ResumeApplication();

// Assert
// Calling 'Register' already generated a trace, so we expect 1+1 calls to ConfigureScope
Assert.AreEqual(initialCallsCount + 1, _fixture.TestHub.ConfigureScopeCalls.Count);
var configureScope = _fixture.TestHub.ConfigureScopeCalls.Last();
var scope = new Scope(_fixture.SentryOptions);
Expand All @@ -72,10 +89,15 @@ public void TraceGeneration_OnApplicationResume_GeneratesNewTrace()
Assert.AreNotEqual(initialPropagationContext, scope.PropagationContext);
}

[Test]
public void TraceGeneration_OnActiveSceneChange_GeneratesNewTrace()
[TestCase(0.0f, false)]
[TestCase(0.0f, true)]
[TestCase(1.0f, false)]
public void ActiveSceneChanged_TracingDisabledOrAutoSceneLoadTracesDisabled_GeneratesTrace(float tracesSampleRate, bool autoSceneLoadTraces)
{
// Arrange
_fixture.SentryOptions.TracesSampleRate = tracesSampleRate;
_fixture.SentryOptions.AutoSceneLoadTraces = autoSceneLoadTraces;

var sut = _fixture.GetSut();
sut.Register(_fixture.TestHub, _fixture.SentryOptions);
var initialCallsCount = _fixture.TestHub.ConfigureScopeCalls.Count;
Expand All @@ -84,13 +106,29 @@ public void TraceGeneration_OnActiveSceneChange_GeneratesNewTrace()
_fixture.SceneManager.OnActiveSceneChanged(new SceneAdapter("from scene name"), new SceneAdapter("to scene name"));

// Assert
// Calling 'Register' already generated a trace, so we expect 1+1 calls to ConfigureScope
Assert.AreEqual(initialCallsCount + 1, _fixture.TestHub.ConfigureScopeCalls.Count);
var configureScope = _fixture.TestHub.ConfigureScopeCalls.Last();
var scope = new Scope(_fixture.SentryOptions);
var initialPropagationContext = scope.PropagationContext;
configureScope(scope);

Assert.AreNotEqual(initialPropagationContext, scope.PropagationContext);
}

[Test]
public void ActiveSceneChanged_TracingEnabledAndAutoSceneLoadTracesEnabled_DoesNotGenerateTrace()
{
// Arrange
_fixture.SentryOptions.TracesSampleRate = 1.0f;
_fixture.SentryOptions.AutoSceneLoadTraces = true;

var sut = _fixture.GetSut();
sut.Register(_fixture.TestHub, _fixture.SentryOptions);
var initialCallsCount = _fixture.TestHub.ConfigureScopeCalls.Count;

// Act
_fixture.SceneManager.OnActiveSceneChanged(new SceneAdapter("from scene name"), new SceneAdapter("to scene name"));

// Assert
Assert.AreEqual(initialCallsCount, _fixture.TestHub.ConfigureScopeCalls.Count);
}
}
Loading