|
1 | 1 | import 'package:collection/collection.dart'; |
| 2 | +import 'package:mockito/mockito.dart'; |
2 | 3 | import 'package:sentry/sentry.dart'; |
3 | 4 | import 'package:sentry/src/client_reports/discard_reason.dart'; |
| 5 | +import 'package:sentry/src/profiling.dart'; |
4 | 6 | import 'package:sentry/src/sentry_tracer.dart'; |
5 | 7 | import 'package:sentry/src/transport/data_category.dart'; |
6 | 8 | import 'package:test/test.dart'; |
7 | 9 |
|
8 | 10 | import 'mocks.dart'; |
| 11 | +import 'mocks.mocks.dart'; |
9 | 12 | import 'mocks/mock_client_report_recorder.dart'; |
10 | 13 | import 'mocks/mock_sentry_client.dart'; |
11 | 14 |
|
@@ -374,6 +377,61 @@ void main() { |
374 | 377 | expect( |
375 | 378 | fixture.client.captureTransactionCalls.first.traceContext, context); |
376 | 379 | }); |
| 380 | + |
| 381 | + test('profiler is not started by default', () async { |
| 382 | + final hub = fixture.getSut(); |
| 383 | + final tr = hub.startTransaction('name', 'op'); |
| 384 | + expect(tr, isA<SentryTracer>()); |
| 385 | + expect((tr as SentryTracer).profiler, isNull); |
| 386 | + }); |
| 387 | + |
| 388 | + test('profiler is started according to the sampling rate', () async { |
| 389 | + final hub = fixture.getSut(); |
| 390 | + final factory = MockProfilerFactory(); |
| 391 | + when(factory.startProfiling(fixture._context)).thenReturn(MockProfiler()); |
| 392 | + hub.profilerFactory = factory; |
| 393 | + |
| 394 | + var tr = hub.startTransactionWithContext(fixture._context); |
| 395 | + expect((tr as SentryTracer).profiler, isNull); |
| 396 | + verifyZeroInteractions(factory); |
| 397 | + |
| 398 | + hub.options.profilesSampleRate = 1.0; |
| 399 | + tr = hub.startTransactionWithContext(fixture._context); |
| 400 | + expect((tr as SentryTracer).profiler, isNotNull); |
| 401 | + verify(factory.startProfiling(fixture._context)).called(1); |
| 402 | + }); |
| 403 | + |
| 404 | + test('profiler.finish() is called', () async { |
| 405 | + final hub = fixture.getSut(); |
| 406 | + final factory = MockProfilerFactory(); |
| 407 | + final profiler = MockProfiler(); |
| 408 | + final expected = MockProfileInfo(); |
| 409 | + when(factory.startProfiling(fixture._context)).thenReturn(profiler); |
| 410 | + when(profiler.finishFor(any)).thenAnswer((_) async => expected); |
| 411 | + |
| 412 | + hub.profilerFactory = factory; |
| 413 | + hub.options.profilesSampleRate = 1.0; |
| 414 | + final tr = hub.startTransactionWithContext(fixture._context); |
| 415 | + await tr.finish(); |
| 416 | + verify(profiler.finishFor(any)).called(1); |
| 417 | + verify(profiler.dispose()).called(1); |
| 418 | + }); |
| 419 | + |
| 420 | + test('profiler.dispose() is called even if not captured', () async { |
| 421 | + final hub = fixture.getSut(); |
| 422 | + final factory = MockProfilerFactory(); |
| 423 | + final profiler = MockProfiler(); |
| 424 | + final expected = MockProfileInfo(); |
| 425 | + when(factory.startProfiling(fixture._context)).thenReturn(profiler); |
| 426 | + when(profiler.finishFor(any)).thenAnswer((_) async => expected); |
| 427 | + |
| 428 | + hub.profilerFactory = factory; |
| 429 | + hub.options.profilesSampleRate = 1.0; |
| 430 | + final tr = hub.startTransactionWithContext(fixture._context); |
| 431 | + await tr.finish(status: SpanStatus.aborted()); |
| 432 | + verify(profiler.dispose()).called(1); |
| 433 | + verifyNever(profiler.finishFor(any)); |
| 434 | + }); |
377 | 435 | }); |
378 | 436 |
|
379 | 437 | group('Hub scope', () { |
@@ -641,10 +699,12 @@ class Fixture { |
641 | 699 |
|
642 | 700 | final hub = Hub(options); |
643 | 701 |
|
| 702 | + // A fully configured context - won't trigger a copy in startTransaction(). |
644 | 703 | _context = SentryTransactionContext( |
645 | 704 | 'name', |
646 | 705 | 'op', |
647 | 706 | samplingDecision: SentryTracesSamplingDecision(sampled!), |
| 707 | + origin: SentryTraceOrigins.manual, |
648 | 708 | ); |
649 | 709 |
|
650 | 710 | tracer = SentryTracer(_context, hub); |
|
0 commit comments