Skip to content

Commit 2675d3c

Browse files
authored
test(session-replay): Add deterministic sample rate to fix flakiness (#6012)
1 parent 3067c23 commit 2675d3c

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

Tests/SentryTests/Integrations/SessionReplay/SentrySessionReplayIntegrationTests.swift

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,24 +272,46 @@ class SentrySessionReplayIntegrationTests: XCTestCase {
272272
}
273273

274274
func testBufferReplayIgnoredBecauseSampleRateForCrash() throws {
275-
startSDK(sessionSampleRate: 1, errorSampleRate: 1)
275+
// -- Arrange --
276+
// Use deterministic random number to avoid flaky test behavior.
277+
// CRITICAL: Set random value to 1.0 to ensure shouldReplayFullSession(sessionSampleRate) returns false,
278+
// preventing the session from starting as a full session. Buffer replay sample rate checks
279+
// only apply to non-full sessions. The sample rate check uses: random >= errorSampleRate
280+
// With errorSampleRate=0 and random=1.0: 1.0 >= 0 = true → replay dropped
281+
SentryDependencyContainer.sharedInstance().random = TestRandom(value: 1.0)
282+
283+
// Start current session with 0% session sample rate to ensure it's NOT a full session
284+
// (shouldReplayFullSession: 1.0 < 0 = false), but 100% error sample rate would normally
285+
// capture all error replays if this were not a buffer replay from previous session
286+
startSDK(sessionSampleRate: 0, errorSampleRate: 1)
276287

277288
let client = SentryClient(options: try XCTUnwrap(SentrySDKInternal.options))
278289
let scope = Scope()
279290
let hub = TestHub(client: client, andScope: scope)
280291
SentrySDKInternal.setCurrentHub(hub)
281292
let expectation = expectation(description: "Replay to be captured")
282-
expectation.isInverted = true
283-
hub.onReplayCapture = {
293+
expectation.isInverted = true // We expect NO replay to be captured
294+
hub.onReplayCapture = {
284295
expectation.fulfill()
285296
}
286-
297+
298+
// -- Act --
299+
// Create a previous session replay file with 0% error sample rate.
300+
// This simulates a previous session that crashed and had error replay disabled.
301+
// The key insight: replay capture decision uses the PREVIOUS session's sample rate,
302+
// not the current session's sample rate, because the replay frames were recorded
303+
// during the previous session with its own sampling configuration.
287304
try createLastSessionReplay(writeSessionInfo: false, errorSampleRate: 0)
288305
let crash = Event(error: NSError(domain: "Error", code: 1))
289306
crash.context = [:]
290307
crash.isFatalEvent = true
291-
globalEventProcessor.reportAll(crash)
292-
308+
globalEventProcessor.reportAll(crash) // This triggers resumePreviousSessionReplay
309+
310+
// -- Assert --
311+
// The replay should be dropped because:
312+
// 1. Previous session had errorSampleRate = 0 (no error replays wanted)
313+
// 2. Sample rate check: 1.0 >= 0 = true → drop replay
314+
// 3. Current session's errorSampleRate = 1 is irrelevant for previous session data
293315
wait(for: [expectation], timeout: 1)
294316
XCTAssertEqual(hub.capturedReplayRecordingVideo.count, 0)
295317
}

0 commit comments

Comments
 (0)