|
1 | 1 | import asyncio |
2 | 2 | import re |
3 | 3 | import sys |
| 4 | +import time |
4 | 5 | from typing import Any |
5 | 6 | from unittest import mock |
6 | 7 |
|
7 | 8 | import pytest |
8 | 9 |
|
9 | 10 | import sentry_sdk |
| 11 | +from sentry_sdk.profiler.continuous_profiler import get_profiler_id |
10 | 12 | from sentry_sdk.traces import NoOpStreamedSpan, SpanStatus, StreamedSpan |
11 | 13 |
|
12 | 14 | minimum_python_38 = pytest.mark.skipif( |
@@ -1322,6 +1324,102 @@ def test_ignore_spans_reparenting(sentry_init, capture_envelopes): |
1322 | 1324 | assert span5["parent_span_id"] == span3["span_id"] |
1323 | 1325 |
|
1324 | 1326 |
|
| 1327 | +@mock.patch("sentry_sdk.profiler.continuous_profiler.DEFAULT_SAMPLING_FREQUENCY", 21) |
| 1328 | +def test_segment_span_has_profiler_id( |
| 1329 | + sentry_init, capture_envelopes, teardown_profiling |
| 1330 | +): |
| 1331 | + sentry_init( |
| 1332 | + traces_sample_rate=1.0, |
| 1333 | + profile_lifecycle="trace", |
| 1334 | + profiler_mode="thread", |
| 1335 | + profile_session_sample_rate=1.0, |
| 1336 | + _experiments={ |
| 1337 | + "trace_lifecycle": "stream", |
| 1338 | + "continuous_profiling_auto_start": True, |
| 1339 | + }, |
| 1340 | + ) |
| 1341 | + envelopes = capture_envelopes() |
| 1342 | + |
| 1343 | + with sentry_sdk.traces.start_span(name="profiled segment"): |
| 1344 | + time.sleep(0.1) |
| 1345 | + |
| 1346 | + sentry_sdk.get_client().flush() |
| 1347 | + time.sleep(0.3) # wait for profiler to flush |
| 1348 | + |
| 1349 | + spans = envelopes_to_spans(envelopes) |
| 1350 | + assert len(spans) == 1 |
| 1351 | + assert "sentry.profiler_id" in spans[0]["attributes"] |
| 1352 | + |
| 1353 | + profile_chunks = [ |
| 1354 | + item |
| 1355 | + for envelope in envelopes |
| 1356 | + for item in envelope.items |
| 1357 | + if item.type == "profile_chunk" |
| 1358 | + ] |
| 1359 | + assert len(profile_chunks) > 0 |
| 1360 | + |
| 1361 | + |
| 1362 | +def test_segment_span_no_profiler_id_when_unsampled( |
| 1363 | + sentry_init, capture_envelopes, teardown_profiling |
| 1364 | +): |
| 1365 | + sentry_init( |
| 1366 | + traces_sample_rate=1.0, |
| 1367 | + profile_lifecycle="trace", |
| 1368 | + profiler_mode="thread", |
| 1369 | + profile_session_sample_rate=0.0, |
| 1370 | + _experiments={ |
| 1371 | + "trace_lifecycle": "stream", |
| 1372 | + "continuous_profiling_auto_start": True, |
| 1373 | + }, |
| 1374 | + ) |
| 1375 | + envelopes = capture_envelopes() |
| 1376 | + |
| 1377 | + with sentry_sdk.traces.start_span(name="segment"): |
| 1378 | + time.sleep(0.05) |
| 1379 | + |
| 1380 | + sentry_sdk.get_client().flush() |
| 1381 | + time.sleep(0.2) |
| 1382 | + |
| 1383 | + spans = envelopes_to_spans(envelopes) |
| 1384 | + assert len(spans) == 1 |
| 1385 | + assert "sentry.profiler_id" not in spans[0]["attributes"] |
| 1386 | + |
| 1387 | + profile_chunks = [ |
| 1388 | + item |
| 1389 | + for envelope in envelopes |
| 1390 | + for item in envelope.items |
| 1391 | + if item.type == "profile_chunk" |
| 1392 | + ] |
| 1393 | + assert len(profile_chunks) == 0 |
| 1394 | + |
| 1395 | + |
| 1396 | +@mock.patch("sentry_sdk.profiler.continuous_profiler.DEFAULT_SAMPLING_FREQUENCY", 21) |
| 1397 | +def test_profile_stops_when_segment_ends( |
| 1398 | + sentry_init, capture_envelopes, teardown_profiling |
| 1399 | +): |
| 1400 | + sentry_init( |
| 1401 | + traces_sample_rate=1.0, |
| 1402 | + profile_lifecycle="trace", |
| 1403 | + profiler_mode="thread", |
| 1404 | + profile_session_sample_rate=1.0, |
| 1405 | + _experiments={ |
| 1406 | + "trace_lifecycle": "stream", |
| 1407 | + "continuous_profiling_auto_start": True, |
| 1408 | + }, |
| 1409 | + ) |
| 1410 | + capture_envelopes() |
| 1411 | + |
| 1412 | + with sentry_sdk.traces.start_span(name="segment") as span: |
| 1413 | + time.sleep(0.1) |
| 1414 | + assert span._continuous_profile is not None |
| 1415 | + assert span._continuous_profile.active is True |
| 1416 | + |
| 1417 | + assert span._continuous_profile.active is False |
| 1418 | + |
| 1419 | + time.sleep(0.3) |
| 1420 | + assert get_profiler_id() is None, "profiler should have stopped" |
| 1421 | + |
| 1422 | + |
1325 | 1423 | def test_transport_format(sentry_init, capture_envelopes): |
1326 | 1424 | sentry_init( |
1327 | 1425 | server_name="test-server", |
|
0 commit comments