@@ -23,7 +23,11 @@ final class SentryContinuousProfilerTests: XCTestCase {
23
23
super. tearDown ( )
24
24
clearTestState ( )
25
25
}
26
-
26
+
27
+ func testSentryProfilerChunkExpirationInterval( ) {
28
+ XCTAssertEqual ( 60 , kSentryProfilerChunkExpirationInterval)
29
+ }
30
+
27
31
func testStartingAndStoppingContinuousProfiler( ) throws {
28
32
try performContinuousProfilingTest ( )
29
33
}
@@ -94,12 +98,12 @@ final class SentryContinuousProfilerTests: XCTestCase {
94
98
XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
95
99
}
96
100
97
- func testClosingSDKStopsProfile( ) {
101
+ func testClosingSDKStopsProfile( ) throws {
98
102
XCTAssertFalse ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
99
103
SentryContinuousProfiler . start ( )
100
104
XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
101
105
SentrySDK . close ( )
102
- assertContinuousProfileStoppage ( )
106
+ try assertContinuousProfileStoppage ( )
103
107
}
104
108
105
109
func testStartingAPerformanceTransactionDoesNotStartProfiler( ) throws {
@@ -118,15 +122,15 @@ final class SentryContinuousProfilerTests: XCTestCase {
118
122
XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
119
123
120
124
// assert that the first chunk was sent
121
- fixture. currentDateProvider. advanceBy ( interval: kSentryProfilerChunkExpirationInterval )
122
- fixture. timeoutTimerFactory. fire ( )
125
+ fixture. currentDateProvider. advanceBy ( interval: 60 )
126
+ try fixture. timeoutTimerFactory. check ( )
123
127
let envelope = try XCTUnwrap ( self . fixture. client? . captureEnvelopeInvocations. last)
124
128
let profileItem = try XCTUnwrap ( envelope. items. first)
125
129
XCTAssertEqual ( " profile_chunk " , profileItem. header. type)
126
130
127
131
// assert that the profiler doesn't stop until after the next timer period elapses
128
132
SentryContinuousProfiler . stop ( )
129
- assertContinuousProfileStoppage ( )
133
+ try assertContinuousProfileStoppage ( )
130
134
131
135
// check that the last full chunk was sent
132
136
let lastEnvelope = try XCTUnwrap ( self . fixture. client? . captureEnvelopeInvocations. last)
@@ -136,13 +140,34 @@ final class SentryContinuousProfilerTests: XCTestCase {
136
140
// check that two chunks were sent in total
137
141
XCTAssertEqual ( 2 , self . fixture. client? . captureEnvelopeInvocations. count)
138
142
}
143
+
144
+ func testChunkSerializationAfterBufferInterval( ) throws {
145
+ SentryContinuousProfiler . start ( )
146
+ XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
147
+
148
+ // Advance time by the buffer interval to trigger chunk serialization
149
+ fixture. currentDateProvider. advanceBy ( interval: 60 )
150
+ try fixture. timeoutTimerFactory. check ( )
151
+
152
+ // Check that a chunk was serialized and sent
153
+ let envelope = try XCTUnwrap ( self . fixture. client? . captureEnvelopeInvocations. last)
154
+ let profileItem = try XCTUnwrap ( envelope. items. first)
155
+ XCTAssertEqual ( " profile_chunk " , profileItem. header. type)
156
+
157
+ // Ensure the profiler is still running
158
+ XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
159
+
160
+ // Stop the profiler
161
+ SentryContinuousProfiler . stop ( )
162
+ try assertContinuousProfileStoppage ( )
163
+ }
139
164
}
140
165
141
166
private extension SentryContinuousProfilerTests {
142
167
func addMockSamples( mockAddresses: [ NSNumber ] ) throws {
143
168
let mockThreadMetadata = SentryProfileTestFixture . ThreadMetadata ( id: 1 , priority: 2 , name: " main " )
144
169
let state = try XCTUnwrap ( SentryContinuousProfiler . profiler ( ) ? . state)
145
- for _ in 0 ..< Int ( kSentryProfilerChunkExpirationInterval ) {
170
+ for _ in 0 ..< Int ( 60 ) {
146
171
fixture. currentDateProvider. advanceBy ( interval: 1 )
147
172
SentryProfilerMocksSwiftCompatible . appendMockBacktrace ( to: state, threadID: mockThreadMetadata. id, threadPriority: mockThreadMetadata. priority, threadName: mockThreadMetadata. name, addresses: mockAddresses)
148
173
}
@@ -159,7 +184,7 @@ private extension SentryContinuousProfilerTests {
159
184
try fixture. gatherMockedContinuousProfileMetrics ( )
160
185
try addMockSamples ( mockAddresses: expectedAddresses)
161
186
fixture. currentDateProvider. advanceBy ( interval: 1 )
162
- fixture. timeoutTimerFactory. fire ( )
187
+ try fixture. timeoutTimerFactory. check ( )
163
188
XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
164
189
try assertValidData ( expectedEnvironment: expectedEnvironment, expectedAddresses: expectedAddresses, countMetricsReadingAtProfileStart: countMetricsReadingAtProfileStart)
165
190
#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst)
@@ -174,13 +199,13 @@ private extension SentryContinuousProfilerTests {
174
199
175
200
XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
176
201
SentryContinuousProfiler . stop ( )
177
- assertContinuousProfileStoppage ( )
202
+ try assertContinuousProfileStoppage ( )
178
203
}
179
204
180
- func assertContinuousProfileStoppage( ) {
205
+ func assertContinuousProfileStoppage( ) throws {
181
206
XCTAssert ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
182
- fixture. currentDateProvider. advance ( by: kSentryProfilerTimeoutInterval )
183
- fixture. timeoutTimerFactory. fire ( )
207
+ fixture. currentDateProvider. advance ( by: 60 )
208
+ try fixture. timeoutTimerFactory. check ( )
184
209
XCTAssertFalse ( SentryContinuousProfiler . isCurrentlyProfiling ( ) )
185
210
}
186
211
0 commit comments