From 1e094d3e5f001e17916563b01d9e85ffc2baffa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Andra=C5=A1ec?= Date: Mon, 17 Jul 2023 12:58:26 +0000 Subject: [PATCH] Send trace origin (#1534) Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> --- CHANGELOG.md | 8 + dart/lib/sentry.dart | 2 + dart/lib/src/http_client/tracing_client.dart | 2 + dart/lib/src/hub.dart | 7 + dart/lib/src/noop_sentry_span.dart | 6 + dart/lib/src/protocol/sentry_span.dart | 12 + .../src/protocol/sentry_trace_context.dart | 11 + dart/lib/src/sentry_span_context.dart | 10 + dart/lib/src/sentry_span_interface.dart | 10 + dart/lib/src/sentry_trace_origins.dart | 21 ++ dart/lib/src/sentry_tracer.dart | 6 + dart/lib/src/sentry_transaction_context.dart | 6 + .../test/http_client/tracing_client_test.dart | 1 + dart/test/hub_test.dart | 17 + dart/test/sentry_span_context_test.dart | 12 +- dart/test/sentry_span_test.dart | 20 +- dart/test/sentry_trace_context_test.dart | 14 +- dart/test/sentry_tracer_test.dart | 7 + .../test/sentry_transaction_context_test.dart | 6 + dio/lib/src/sentry_transformer.dart | 6 + dio/lib/src/tracing_client_adapter.dart | 3 + dio/test/sentry_transformer_test.dart | 5 + dio/test/tracing_client_adapter_test.dart | 1 + file/lib/src/sentry_file.dart | 3 + file/test/sentry_file_test.dart | 7 + .../navigation/sentry_navigator_observer.dart | 3 + flutter/lib/src/sentry_asset_bundle.dart | 16 + flutter/test/mocks.dart | 2 +- flutter/test/mocks.mocks.dart | 12 +- flutter/test/native_scope_observer_test.dart | 2 +- flutter/test/sentry_asset_bundle_test.dart | 18 +- sqflite/lib/src/sentry_batch.dart | 4 + sqflite/lib/src/sentry_database.dart | 4 + sqflite/lib/src/sentry_database_executor.dart | 22 ++ sqflite/lib/src/sentry_sqflite.dart | 2 + .../src/sentry_sqflite_database_factory.dart | 4 + sqflite/test/mocks/mocks.mocks.dart | 320 ++++++++++-------- sqflite/test/sentry_batch_test.dart | 30 ++ sqflite/test/sentry_database_test.dart | 160 +++++++++ ...ry_sqflite_database_factory_dart_test.dart | 6 + sqflite/test/sentry_sqflite_test.dart | 19 +- 41 files changed, 667 insertions(+), 160 deletions(-) create mode 100644 dart/lib/src/sentry_trace_origins.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index bd21c716a0..f049c3ddd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +### Features + +- Send trace origin ([#1534](https://github.com/getsentry/sentry-dart/pull/1534)) + +[Trace origin](https://develop.sentry.dev/sdk/performance/trace-origin/) indicates what created a trace or a span. Not all transactions and spans contain enough information to tell whether the user or what precisely in the SDK created it. Origin solves this problem. The SDK now sends origin for transactions and spans. + ## 7.8.0 ### Enhancements diff --git a/dart/lib/sentry.dart b/dart/lib/sentry.dart index 2f12688f82..f23525bfda 100644 --- a/dart/lib/sentry.dart +++ b/dart/lib/sentry.dart @@ -44,3 +44,5 @@ export 'src/utils/http_sanitizer.dart'; export 'src/utils/url_details.dart'; // ignore: invalid_export_of_internal_element export 'src/utils/http_header_utils.dart'; +// ignore: invalid_export_of_internal_element +export 'src/sentry_trace_origins.dart'; diff --git a/dart/lib/src/http_client/tracing_client.dart b/dart/lib/src/http_client/tracing_client.dart index 2615b97aef..ae7a81e973 100644 --- a/dart/lib/src/http_client/tracing_client.dart +++ b/dart/lib/src/http_client/tracing_client.dart @@ -2,6 +2,7 @@ import 'package:http/http.dart'; import '../hub.dart'; import '../hub_adapter.dart'; import '../protocol.dart'; +import '../sentry_trace_origins.dart'; import '../tracing.dart'; import '../utils/tracing_utils.dart'; import '../utils/http_sanitizer.dart'; @@ -33,6 +34,7 @@ class TracingClient extends BaseClient { 'http.client', description: description, ); + span?.origin = SentryTraceOrigins.autoHttpHttp; // if the span is NoOp, we don't want to attach headers if (span is NoOpSentrySpan) { diff --git a/dart/lib/src/hub.dart b/dart/lib/src/hub.dart index f863adcb7b..e1ffe802dd 100644 --- a/dart/lib/src/hub.dart +++ b/dart/lib/src/hub.dart @@ -398,6 +398,7 @@ class Hub { name, operation, description: description, + origin: SentryTraceOrigins.manual, ), startTimestamp: startTimestamp, bindToScope: bindToScope, @@ -442,6 +443,12 @@ class Hub { transactionContext.copyWith(samplingDecision: samplingDecision); } + if (transactionContext.origin == null) { + transactionContext = transactionContext.copyWith( + origin: SentryTraceOrigins.manual, + ); + } + final tracer = SentryTracer( transactionContext, this, diff --git a/dart/lib/src/noop_sentry_span.dart b/dart/lib/src/noop_sentry_span.dart index bdf91f7aca..2156aeb678 100644 --- a/dart/lib/src/noop_sentry_span.dart +++ b/dart/lib/src/noop_sentry_span.dart @@ -51,6 +51,12 @@ class NoOpSentrySpan extends ISentrySpan { @override SentrySpanContext get context => _spanContext; + @override + String? get origin => null; + + @override + set origin(String? origin) {} + @override SpanStatus? get status => null; diff --git a/dart/lib/src/protocol/sentry_span.dart b/dart/lib/src/protocol/sentry_span.dart index 522287330e..e03410d715 100644 --- a/dart/lib/src/protocol/sentry_span.dart +++ b/dart/lib/src/protocol/sentry_span.dart @@ -36,6 +36,7 @@ class SentrySpan extends ISentrySpan { }) { _startTimestamp = startTimestamp?.toUtc() ?? _hub.options.clock(); _finishedCallback = finishedCallback; + _origin = _context.origin; } @override @@ -145,6 +146,14 @@ class SentrySpan extends ISentrySpan { @override SentrySpanContext get context => _context; + String? _origin; + + @override + String? get origin => _origin; + + @override + set origin(String? origin) => _origin = origin; + Map toJson() { final json = _context.toJson(); json['start_timestamp'] = @@ -162,6 +171,9 @@ class SentrySpan extends ISentrySpan { if (_tags.isNotEmpty) { json['tags'] = _tags; } + if (_origin != null) { + json['origin'] = _origin; + } return json; } diff --git a/dart/lib/src/protocol/sentry_trace_context.dart b/dart/lib/src/protocol/sentry_trace_context.dart index 5816e4367d..fab3d1444d 100644 --- a/dart/lib/src/protocol/sentry_trace_context.dart +++ b/dart/lib/src/protocol/sentry_trace_context.dart @@ -28,6 +28,13 @@ class SentryTraceContext { /// The Span status final SpanStatus? status; + /// The origin of the span indicates what created the span. + /// + /// @note Gets set by the SDK. It is not expected to be set manually by users. + /// + /// @see + final String? origin; + factory SentryTraceContext.fromJson(Map json) { return SentryTraceContext( operation: json['op'] as String, @@ -41,6 +48,7 @@ class SentryTraceContext { ? null : SpanStatus.fromString(json['status'] as String), sampled: true, + origin: json['origin'] == null ? null : json['origin'] as String?, ); } @@ -53,6 +61,7 @@ class SentryTraceContext { if (parentSpanId != null) 'parent_span_id': parentSpanId!.toString(), if (description != null) 'description': description, if (status != null) 'status': status!.toString(), + if (origin != null) 'origin': origin, }; } @@ -64,6 +73,7 @@ class SentryTraceContext { status: status, parentSpanId: parentSpanId, sampled: sampled, + origin: origin, ); SentryTraceContext({ @@ -74,6 +84,7 @@ class SentryTraceContext { required this.operation, this.description, this.status, + this.origin, }) : traceId = traceId ?? SentryId.newId(), spanId = spanId ?? SpanId.newId(); } diff --git a/dart/lib/src/sentry_span_context.dart b/dart/lib/src/sentry_span_context.dart index 253ae53977..1b1274c4d0 100644 --- a/dart/lib/src/sentry_span_context.dart +++ b/dart/lib/src/sentry_span_context.dart @@ -20,6 +20,13 @@ class SentrySpanContext { /// consistent across instances of the span. final String? description; + /// The origin of the span indicates what created the span. + /// + /// Gets set by the SDK. It is not expected to be set manually by users. + /// + /// See https://develop.sentry.dev/sdk/performance/trace-origin + final String? origin; + /// Item encoded as JSON Map toJson() { return { @@ -28,6 +35,7 @@ class SentrySpanContext { 'op': operation, if (parentSpanId != null) 'parent_span_id': parentSpanId.toString(), if (description != null) 'description': description, + if (origin != null) 'origin': origin, }; } @@ -37,6 +45,7 @@ class SentrySpanContext { this.parentSpanId, required this.operation, this.description, + this.origin, }) : traceId = traceId ?? SentryId.newId(), spanId = spanId ?? SpanId.newId(); @@ -53,6 +62,7 @@ class SentrySpanContext { parentSpanId: parentSpanId, sampled: sampled, status: status, + origin: origin, ); } } diff --git a/dart/lib/src/sentry_span_interface.dart b/dart/lib/src/sentry_span_interface.dart index 23b3e0637a..cdc121f849 100644 --- a/dart/lib/src/sentry_span_interface.dart +++ b/dart/lib/src/sentry_span_interface.dart @@ -36,6 +36,16 @@ abstract class ISentrySpan { /// Gets the span context. SentrySpanContext get context; + /// Gets the span origin + String? get origin; + + /// Sets span origin. + /// + /// Gets set by the SDK. It is not expected to be set manually by users. + /// + /// See https://develop.sentry.dev/sdk/performance/trace-origin + set origin(String? origin); + /// Returns the end timestamp if finished DateTime? get endTimestamp; diff --git a/dart/lib/src/sentry_trace_origins.dart b/dart/lib/src/sentry_trace_origins.dart new file mode 100644 index 0000000000..e3fd4dbafc --- /dev/null +++ b/dart/lib/src/sentry_trace_origins.dart @@ -0,0 +1,21 @@ +import 'package:meta/meta.dart'; + +@internal +class SentryTraceOrigins { + static const manual = 'manual'; + + static const autoNavigationRouteObserver = 'auto.navigation.route_observer'; + static const autoHttpHttp = 'auto.http.http'; + static const autoHttpDioHttpClientAdapter = + 'auto.http.dio.http_client_adapter'; + static const autoHttpDioTransformer = 'auto.http.dio.transformer'; + static const autoFile = 'auto.file'; + static const autoFileAssetBundle = 'auto.file.asset_bundle'; + static const autoDbSqfliteOpenDatabase = 'auto.db.sqflite.open_database'; + static const autoDbSqfliteBatch = 'auto.db.sqflite.batch'; + static const autoDbSqfliteDatabase = 'auto.db.sqflite.database'; + static const autoDbSqfliteDatabaseExecutor = + 'auto.db.sqflite.database_executor'; + static const autoDbSqfliteDatabaseFactory = + 'auto.db.sqflite.database_factory'; +} diff --git a/dart/lib/src/sentry_tracer.dart b/dart/lib/src/sentry_tracer.dart index 622eaaa3da..2ca82a91ca 100644 --- a/dart/lib/src/sentry_tracer.dart +++ b/dart/lib/src/sentry_tracer.dart @@ -255,6 +255,12 @@ class SentryTracer extends ISentrySpan { @override SentrySpanContext get context => _rootSpan.context; + @override + String? get origin => _rootSpan.origin; + + @override + set origin(String? origin) => _rootSpan.origin = origin; + @override DateTime get startTimestamp => _rootSpan.startTimestamp; diff --git a/dart/lib/src/sentry_transaction_context.dart b/dart/lib/src/sentry_transaction_context.dart index e758acd7a1..66024459f5 100644 --- a/dart/lib/src/sentry_transaction_context.dart +++ b/dart/lib/src/sentry_transaction_context.dart @@ -1,4 +1,5 @@ import 'package:meta/meta.dart'; +import 'sentry_trace_origins.dart'; import 'protocol.dart'; import 'sentry_baggage.dart'; @@ -21,12 +22,14 @@ class SentryTransactionContext extends SentrySpanContext { SpanId? parentSpanId, this.transactionNameSource, this.samplingDecision, + String? origin, }) : super( operation: operation, description: description, traceId: traceId, spanId: spanId, parentSpanId: parentSpanId, + origin: origin, ); factory SentryTransactionContext.fromSentryTrace( @@ -50,6 +53,7 @@ class SentryTransactionContext extends SentrySpanContext { : null, transactionNameSource: transactionNameSource ?? SentryTransactionNameSource.custom, + origin: SentryTraceOrigins.manual, ); } @@ -63,6 +67,7 @@ class SentryTransactionContext extends SentrySpanContext { SpanId? parentSpanId, SentryTransactionNameSource? transactionNameSource, SentryTracesSamplingDecision? samplingDecision, + String? origin, }) => SentryTransactionContext( name ?? this.name, @@ -76,5 +81,6 @@ class SentryTransactionContext extends SentrySpanContext { transactionNameSource: transactionNameSource ?? this.transactionNameSource, samplingDecision: samplingDecision ?? this.samplingDecision, + origin: origin ?? this.origin, ); } diff --git a/dart/test/http_client/tracing_client_test.dart b/dart/test/http_client/tracing_client_test.dart index d024cccd0f..dce3b3ef31 100644 --- a/dart/test/http_client/tracing_client_test.dart +++ b/dart/test/http_client/tracing_client_test.dart @@ -44,6 +44,7 @@ void main() { expect(span.data['http.fragment'], 'baz'); expect(span.data['http.response.status_code'], 200); expect(span.data['http.response_content_length'], 2); + expect(span.origin, SentryTraceOrigins.autoHttpHttp); }); test('finish span if errored request', () async { diff --git a/dart/test/hub_test.dart b/dart/test/hub_test.dart index 5b11204d70..32e0f1021c 100644 --- a/dart/test/hub_test.dart +++ b/dart/test/hub_test.dart @@ -176,6 +176,7 @@ void main() { expect(tr.context.description, 'desc'); expect(tr.startTimestamp.isAtSameMomentAs(startTime), true); expect((tr as SentryTracer).name, 'name'); + expect(tr.origin, SentryTraceOrigins.manual); }); test('start transaction binds span to the scope', () async { @@ -265,6 +266,22 @@ void main() { expect(tr.samplingDecision?.sampled, false); }); + test('start transaction with context sets trace origin fallback', () async { + final hub = fixture.getSut(); + final tr = hub.startTransactionWithContext( + SentryTransactionContext('name', 'op'), + ); + expect(tr.origin, SentryTraceOrigins.manual); + }); + + test('start transaction with context keeps origin', () async { + final hub = fixture.getSut(); + final tr = hub.startTransactionWithContext( + SentryTransactionContext('name', 'op', origin: 'auto.navigation.test'), + ); + expect(tr.origin, 'auto.navigation.test'); + }); + test('start transaction return NoOp if performance is disabled', () async { final hub = fixture.getSut(tracesSampleRate: null); diff --git a/dart/test/sentry_span_context_test.dart b/dart/test/sentry_span_context_test.dart index 22d7657a00..81e651dc6e 100644 --- a/dart/test/sentry_span_context_test.dart +++ b/dart/test/sentry_span_context_test.dart @@ -14,9 +14,10 @@ void main() { expect(map['op'], 'op'); expect(map['parent_span_id'], isNotNull); expect(map['description'], 'desc'); + expect(map['origin'], 'manual'); }); - test('toTraceContext gets sampled and status', () { + test('toTraceContext gets sampled, status, and origin', () { final sut = fixture.getSut(); final aborted = SpanStatus.aborted(); final traceContext = sut.toTraceContext( @@ -31,15 +32,16 @@ void main() { expect(traceContext.parentSpanId, isNotNull); expect(traceContext.description, 'desc'); expect(traceContext.status, aborted); + expect(traceContext.origin, 'manual'); }); } class Fixture { SentrySpanContext getSut() { return SentrySpanContext( - operation: 'op', - parentSpanId: SpanId.newId(), - description: 'desc', - ); + operation: 'op', + parentSpanId: SpanId.newId(), + description: 'desc', + origin: 'manual'); } } diff --git a/dart/test/sentry_span_test.dart b/dart/test/sentry_span_test.dart index c9820485fb..37a81309da 100644 --- a/dart/test/sentry_span_test.dart +++ b/dart/test/sentry_span_test.dart @@ -90,6 +90,14 @@ void main() { expect(sut.data['test'], isNull); }); + test('span sets origin', () { + final sut = fixture.getSut(); + + sut.origin = 'manual'; + + expect(sut.origin, 'manual'); + }); + test('span adds tag', () { final sut = fixture.getSut(); @@ -122,6 +130,7 @@ void main() { sut.setTag('test', 'test'); sut.setData('test', 'test'); + sut.origin = 'manual'; await sut.finish(status: SpanStatus.aborted()); @@ -132,6 +141,7 @@ void main() { expect(map['data']['test'], 'test'); expect(map['tags']['test'], 'test'); expect(map['status'], 'aborted'); + expect(map['origin'], 'manual'); }); test('finished returns false if not yet', () { @@ -257,13 +267,15 @@ void main() { expect(currentTimer, isNot(equals(newTimer))); }); + + test('takes origin from context', () async { + final sut = fixture.getSut(); + expect(sut.origin, 'manual'); + }); } class Fixture { - final context = SentryTransactionContext( - 'name', - 'op', - ); + final context = SentryTransactionContext('name', 'op', origin: 'manual'); late SentryTracer tracer; final hub = MockHub(); diff --git a/dart/test/sentry_trace_context_test.dart b/dart/test/sentry_trace_context_test.dart index 2e287b9024..dde599bef1 100644 --- a/dart/test/sentry_trace_context_test.dart +++ b/dart/test/sentry_trace_context_test.dart @@ -15,6 +15,7 @@ void main() { expect(map['parent_span_id'], isNotNull); expect(map['description'], 'desc'); expect(map['status'], 'aborted'); + expect(map['origin'], 'auto.ui'); }); test('fromJson deserializes', () { @@ -25,6 +26,7 @@ void main() { 'parent_span_id': '0000000000000000', 'description': 'desc', 'status': 'aborted', + 'origin': 'auto.ui' }; final traceContext = SentryTraceContext.fromJson(map); @@ -41,11 +43,11 @@ void main() { class Fixture { SentryTraceContext getSut() { return SentryTraceContext( - operation: 'op', - parentSpanId: SpanId.newId(), - description: 'desc', - sampled: true, - status: SpanStatus.aborted(), - ); + operation: 'op', + parentSpanId: SpanId.newId(), + description: 'desc', + sampled: true, + status: SpanStatus.aborted(), + origin: 'auto.ui'); } } diff --git a/dart/test/sentry_tracer_test.dart b/dart/test/sentry_tracer_test.dart index e0818e71fa..f2c0bcdf7c 100644 --- a/dart/test/sentry_tracer_test.dart +++ b/dart/test/sentry_tracer_test.dart @@ -33,6 +33,12 @@ void main() { expect(sut.samplingDecision?.sampled, isTrue); }); + test('tracer origin from root span', () { + final sut = fixture.getSut(); + + expect(sut.origin, 'manual'); + }); + test('tracer finishes with status', () async { final sut = fixture.getSut(); @@ -585,6 +591,7 @@ class Fixture { 'name', 'op', samplingDecision: SentryTracesSamplingDecision(sampled!), + origin: 'manual', ); return SentryTracer( context, diff --git a/dart/test/sentry_transaction_context_test.dart b/dart/test/sentry_transaction_context_test.dart index 7fc2602262..09330d0afd 100644 --- a/dart/test/sentry_transaction_context_test.dart +++ b/dart/test/sentry_transaction_context_test.dart @@ -67,4 +67,10 @@ void main() { expect(context.parentSamplingDecision?.sampleRate, 1.0); }); + + test('origin set to manual', () { + final context = getSentryTransactionContext(); + + expect(context.origin, SentryTraceOrigins.manual); + }); } diff --git a/dio/lib/src/sentry_transformer.dart b/dio/lib/src/sentry_transformer.dart index cdc7aa5342..5b43afbfeb 100644 --- a/dio/lib/src/sentry_transformer.dart +++ b/dio/lib/src/sentry_transformer.dart @@ -28,6 +28,9 @@ class SentryTransformer implements Transformer { ); span?.setData('http.method', options.method); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoHttpDioTransformer; + urlDetails?.applyToSpan(span); String? request; @@ -63,6 +66,9 @@ class SentryTransformer implements Transformer { ); span?.setData('http.method', options.method); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoHttpDioTransformer; + urlDetails?.applyToSpan(span); dynamic transformedResponse; diff --git a/dio/lib/src/tracing_client_adapter.dart b/dio/lib/src/tracing_client_adapter.dart index 5218dad1d7..506339e7d4 100644 --- a/dio/lib/src/tracing_client_adapter.dart +++ b/dio/lib/src/tracing_client_adapter.dart @@ -38,6 +38,9 @@ class TracingClientAdapter implements HttpClientAdapter { description: description, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoHttpDioHttpClientAdapter; + // if the span is NoOp, we don't want to attach headers if (span is NoOpSentrySpan) { span = null; diff --git a/dio/test/sentry_transformer_test.dart b/dio/test/sentry_transformer_test.dart index 125acba558..492f6e9b23 100644 --- a/dio/test/sentry_transformer_test.dart +++ b/dio/test/sentry_transformer_test.dart @@ -43,6 +43,8 @@ void main() { expect(span.data['url'], 'https://example.com'); expect(span.data['http.query'], 'foo=bar'); expect(span.data['http.fragment'], 'baz'); + expect(span.data['http.fragment'], 'baz'); + expect(span.origin, SentryTraceOrigins.autoHttpDioTransformer); }); test('transformRequest finish span if errored request', () async { @@ -70,6 +72,7 @@ void main() { expect(span.data['http.query'], 'foo=bar'); expect(span.data['http.fragment'], 'baz'); expect(span.finished, true); + expect(span.origin, SentryTraceOrigins.autoHttpDioTransformer); }); test('transformResponse creates span', () async { @@ -97,6 +100,7 @@ void main() { expect(span.data['url'], 'https://example.com'); expect(span.data['http.query'], 'foo=bar'); expect(span.data['http.fragment'], 'baz'); + expect(span.origin, SentryTraceOrigins.autoHttpDioTransformer); }); test('transformResponse finish span if errored request', () async { @@ -127,6 +131,7 @@ void main() { expect(span.data['http.query'], 'foo=bar'); expect(span.data['http.fragment'], 'baz'); expect(span.finished, true); + expect(span.origin, SentryTraceOrigins.autoHttpDioTransformer); }); }); } diff --git a/dio/test/tracing_client_adapter_test.dart b/dio/test/tracing_client_adapter_test.dart index 0f3e0d3869..e0d07d527d 100644 --- a/dio/test/tracing_client_adapter_test.dart +++ b/dio/test/tracing_client_adapter_test.dart @@ -49,6 +49,7 @@ void main() { expect(span.data['http.fragment'], 'baz'); expect(span.data['http.response.status_code'], 200); expect(span.data['http.response_content_length'], 2); + expect(span.origin, SentryTraceOrigins.autoHttpDioHttpClientAdapter); }); test('finish span if errored request', () async { diff --git a/file/lib/src/sentry_file.dart b/file/lib/src/sentry_file.dart index 2cb667e6ea..4b7659dc0c 100644 --- a/file/lib/src/sentry_file.dart +++ b/file/lib/src/sentry_file.dart @@ -423,6 +423,7 @@ class SentryFile implements File { final currentSpan = _hub.getSpan(); final span = currentSpan?.startChild(operation, description: desc); + span?.origin = SentryTraceOrigins.autoFile; span?.setData('file.async', true); if (_hub.options.sendDefaultPii) { span?.setData('file.path', absolute.path); @@ -470,6 +471,8 @@ class SentryFile implements File { final currentSpan = _hub.getSpan(); final span = currentSpan?.startChild(operation, description: desc); + + span?.origin = SentryTraceOrigins.autoFile; span?.setData('file.async', false); if (_hub.options.sendDefaultPii) { diff --git a/file/test/sentry_file_test.dart b/file/test/sentry_file_test.dart index 62c5afb070..a3fc47f670 100644 --- a/file/test/sentry_file_test.dart +++ b/file/test/sentry_file_test.dart @@ -33,6 +33,7 @@ void main() { (span.data['file.path'] as String) .endsWith('test_resources/testfile.txt'), true); + expect(span.origin, SentryTraceOrigins.autoFile); } test('async', () async { @@ -103,6 +104,7 @@ void main() { (span.data['file.path'] as String) .endsWith('test_resources/testfile_create.txt'), true); + expect(span.origin, SentryTraceOrigins.autoFile); } test('async', () async { @@ -171,6 +173,7 @@ void main() { (span.data['file.path'] as String) .endsWith('test_resources/testfile_delete.txt'), true); + expect(span.origin, SentryTraceOrigins.autoFile); } test('async', () async { @@ -237,6 +240,7 @@ void main() { (span.data['file.path'] as String) .endsWith('test_resources/sentry.png'), true); + expect(span.origin, SentryTraceOrigins.autoFile); } test('async', () async { @@ -279,6 +283,7 @@ void main() { (span.data['file.path'] as String) .endsWith('test_resources/$fileName'), true); + expect(span.origin, SentryTraceOrigins.autoFile); } test('as bytes async', () async { @@ -408,6 +413,7 @@ void main() { expect( (span.data['file.path'] as String).endsWith('test_resources/$name'), true); + expect(span.origin, SentryTraceOrigins.autoFile); } test('async', () async { @@ -476,6 +482,7 @@ void main() { expect(span.data['file.async'], async); expect(span.data['file.path'], null); + expect(span.origin, SentryTraceOrigins.autoFile); } test('does not add file path if sendDefaultPii is disabled async', diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index de5b51c52e..135d131ec2 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -179,7 +179,10 @@ class SentryNavigatorObserver extends RouteObserver> { name, 'navigation', transactionNameSource: SentryTransactionNameSource.component, + // ignore: invalid_use_of_internal_member + origin: SentryTraceOrigins.autoNavigationRouteObserver, ); + _transaction = _hub.startTransactionWithContext( transactionContext, waitForChildren: true, diff --git a/flutter/lib/src/sentry_asset_bundle.dart b/flutter/lib/src/sentry_asset_bundle.dart index 10a3cd9bcc..52d1a2da0c 100644 --- a/flutter/lib/src/sentry_asset_bundle.dart +++ b/flutter/lib/src/sentry_asset_bundle.dart @@ -61,6 +61,8 @@ class SentryAssetBundle implements AssetBundle { ); span?.setData('file.path', key); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; ByteData? data; try { @@ -95,6 +97,8 @@ class SentryAssetBundle implements AssetBundle { 'AssetBundle.loadStructuredData<$T>: ${_fileName(key)}', ); span?.setData('file.path', key); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; final completer = Completer(); @@ -137,6 +141,8 @@ class SentryAssetBundle implements AssetBundle { 'AssetBundle.loadStructuredBinaryData<$T>: ${_fileName(key)}', ); span?.setData('file.path', key); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; final completer = Completer(); @@ -180,6 +186,8 @@ class SentryAssetBundle implements AssetBundle { span?.setData('file.path', key); span?.setData('from-cache', cache); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; String? data; try { @@ -237,6 +245,8 @@ class SentryAssetBundle implements AssetBundle { ); span?.setData('file.path', key); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; ImmutableBuffer data; try { @@ -282,6 +292,9 @@ class SentryAssetBundle implements AssetBundle { 'serialize.file.read', description: 'parsing "$key" to "$T"', ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; + T data; try { data = await parser(value); @@ -307,6 +320,9 @@ class SentryAssetBundle implements AssetBundle { 'serialize.file.read', description: 'parsing "$key" to "$T"', ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoFileAssetBundle; + T data; try { final result = parser(value); diff --git a/flutter/test/mocks.dart b/flutter/test/mocks.dart index 4a73e86b3b..28da5e6bff 100644 --- a/flutter/test/mocks.dart +++ b/flutter/test/mocks.dart @@ -156,7 +156,7 @@ class NoOpHub with NoSuchMethodProvider implements Hub { bool get isEnabled => false; } -class MockSentryNative implements SentryNative { +class TestMockSentryNative implements SentryNative { @override DateTime? appStartEnd; diff --git a/flutter/test/mocks.mocks.dart b/flutter/test/mocks.mocks.dart index 4b2c083bff..70a42aff77 100644 --- a/flutter/test/mocks.mocks.dart +++ b/flutter/test/mocks.mocks.dart @@ -1,5 +1,5 @@ -// Mocks generated by Mockito 5.3.2 from annotations -// in sentry_flutter/example/windows/flutter/ephemeral/.plugin_symlinks/sentry_flutter/example/linux/flutter/ephemeral/.plugin_symlinks/sentry_flutter/example/ios/.symlinks/plugins/sentry_flutter/test/mocks.dart. +// Mocks generated by Mockito 5.4.2 from annotations +// in sentry_flutter/test/mocks.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -188,6 +188,14 @@ class MockSentryTracer extends _i1.Mock implements _i8.SentryTracer { ), ) as _i2.SentrySpanContext); @override + set origin(String? origin) => super.noSuchMethod( + Invocation.setter( + #origin, + origin, + ), + returnValueForMissingStub: null, + ); + @override DateTime get startTimestamp => (super.noSuchMethod( Invocation.getter(#startTimestamp), returnValue: _FakeDateTime_1( diff --git a/flutter/test/native_scope_observer_test.dart b/flutter/test/native_scope_observer_test.dart index aaad8a7044..0efb22a2c1 100644 --- a/flutter/test/native_scope_observer_test.dart +++ b/flutter/test/native_scope_observer_test.dart @@ -89,7 +89,7 @@ void main() { } class Fixture { - var mock = MockSentryNative(); + var mock = TestMockSentryNative(); NativeScopeObserver getSut() { final sut = NativeScopeObserver(mock); diff --git a/flutter/test/sentry_asset_bundle_test.dart b/flutter/test/sentry_asset_bundle_test.dart index 8a2d2d9527..c5236f674a 100644 --- a/flutter/test/sentry_asset_bundle_test.dart +++ b/flutter/test/sentry_asset_bundle_test.dart @@ -48,6 +48,7 @@ void main() { expect(span.data['file.path'], ''); expect(span.data['file.size'], 0); expect(span.context.description, 'AssetBundle.load: '); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test('load: creates a span if transaction is bound to scope', () async { @@ -71,6 +72,7 @@ void main() { expect(span.data['file.path'], 'resources/test.txt'); expect(span.data['file.size'], 12); expect(span.context.description, 'AssetBundle.load: test.txt'); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test('load: end span with error if exception is thrown', () async { @@ -94,6 +96,7 @@ void main() { expect(span.finished, true); expect(span.context.operation, 'file.read'); expect(span.context.description, 'AssetBundle.load: test.txt'); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test('loadString: creates a span if transaction is bound to scope', @@ -118,6 +121,7 @@ void main() { expect(span.data['file.path'], 'resources/test.txt'); expect(span.data['from-cache'], true); expect(span.context.description, 'AssetBundle.loadString: test.txt'); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test('loadString: end span with error if exception is thrown', () async { @@ -140,6 +144,7 @@ void main() { expect(span.finished, true); expect(span.context.operation, 'file.read'); expect(span.context.description, 'AssetBundle.loadString: test.txt'); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test('loadBuffer: creates a span if transaction is bound to scope', @@ -164,6 +169,7 @@ void main() { expect(span.data['file.path'], 'resources/test.txt'); expect(span.data['file.size'], 12); expect(span.context.description, 'AssetBundle.loadBuffer: test.txt'); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test('loadBuffer: end span with error if exception is thrown', () async { @@ -187,10 +193,11 @@ void main() { expect(span.finished, true); expect(span.context.operation, 'file.read'); expect(span.context.description, 'AssetBundle.loadBuffer: test.txt'); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }); test( - 'loadStructuredData: does not create any spans and just forwords the call to the underlying assetbundle if disabled', + 'loadStructuredData: does not create any spans and just forwards the call to the underlying assetbundle if disabled', () async { final sut = fixture.getSut(structuredDataTracing: false); final tr = fixture._hub.startTransaction( @@ -243,6 +250,7 @@ void main() { span.context.description, 'AssetBundle.loadStructuredData: test.txt', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }, ); @@ -278,6 +286,7 @@ void main() { span.context.description, 'AssetBundle.loadStructuredData: test.txt', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); span = tracer.children[1]; @@ -289,6 +298,7 @@ void main() { span.context.description, 'parsing "resources/test.txt" to "String"', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }, ); @@ -321,6 +331,7 @@ void main() { span.context.description, 'AssetBundle.loadStructuredData: test.txt', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); span = tracer.children[1]; @@ -331,6 +342,7 @@ void main() { span.context.description, 'parsing "resources/test.txt" to "String"', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }, ); @@ -393,6 +405,7 @@ void main() { span.context.description, 'AssetBundle.loadStructuredBinaryData: test.txt', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }, ); @@ -439,6 +452,7 @@ void main() { span.context.description, 'parsing "resources/test.txt" to "String"', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }, ); @@ -473,6 +487,7 @@ void main() { span.context.description, 'AssetBundle.loadStructuredBinaryData: test.txt', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); span = tracer.children[1]; @@ -483,6 +498,7 @@ void main() { span.context.description, 'parsing "resources/test.txt" to "String"', ); + expect(span.origin, SentryTraceOrigins.autoFileAssetBundle); }, ); diff --git a/sqflite/lib/src/sentry_batch.dart b/sqflite/lib/src/sentry_batch.dart index 762f62ac80..95949125bd 100644 --- a/sqflite/lib/src/sentry_batch.dart +++ b/sqflite/lib/src/sentry_batch.dart @@ -47,6 +47,8 @@ class SentryBatch implements Batch { SentryDatabase.dbOp, description: _buffer.toString().trim(), ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteBatch; try { final result = await _batch.apply( @@ -82,6 +84,8 @@ class SentryBatch implements Batch { SentryDatabase.dbOp, description: _buffer.toString().trim(), ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteBatch; try { final result = await _batch.commit( diff --git a/sqflite/lib/src/sentry_database.dart b/sqflite/lib/src/sentry_database.dart index 345924349d..f47551cff8 100644 --- a/sqflite/lib/src/sentry_database.dart +++ b/sqflite/lib/src/sentry_database.dart @@ -60,6 +60,8 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { dbOp, description: 'Close DB: ${_database.path}', ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabase; try { await _database.close(); @@ -109,6 +111,8 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database { _dbSqlOp, description: 'Transaction DB: ${_database.path}', ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabase; Future newAction(Transaction txn) async { final executor = diff --git a/sqflite/lib/src/sentry_database_executor.dart b/sqflite/lib/src/sentry_database_executor.dart index e00896eef6..b43d13c8d6 100644 --- a/sqflite/lib/src/sentry_database_executor.dart +++ b/sqflite/lib/src/sentry_database_executor.dart @@ -39,6 +39,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: builder.sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = @@ -66,6 +68,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { await _executor.execute(sql, arguments); @@ -101,6 +105,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: builder.sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.insert( @@ -155,6 +161,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlQueryOp, description: builder.sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.query( @@ -216,6 +224,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlQueryOp, description: builder.sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.queryCursor( @@ -254,6 +264,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.rawDelete(sql, arguments); @@ -280,6 +292,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.rawInsert(sql, arguments); @@ -309,6 +323,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlQueryOp, description: sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.rawQuery(sql, arguments); @@ -339,6 +355,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlQueryOp, description: sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.rawQueryCursor( @@ -369,6 +387,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.rawUpdate(sql, arguments); @@ -408,6 +428,8 @@ class SentryDatabaseExecutor implements DatabaseExecutor { SentryDatabase.dbSqlExecuteOp, description: builder.sql, ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor; try { final result = await _executor.update( diff --git a/sqflite/lib/src/sentry_sqflite.dart b/sqflite/lib/src/sentry_sqflite.dart index 79c609df62..ebd39b547b 100644 --- a/sqflite/lib/src/sentry_sqflite.dart +++ b/sqflite/lib/src/sentry_sqflite.dart @@ -44,6 +44,8 @@ Future openDatabaseWithSentry( SentryDatabase.dbOp, description: 'Open DB: $path', ); + // ignore: invalid_use_of_internal_member + span?.origin = SentryTraceOrigins.autoDbSqfliteOpenDatabase; try { final database = diff --git a/sqflite/lib/src/sentry_sqflite_database_factory.dart b/sqflite/lib/src/sentry_sqflite_database_factory.dart index 8196e4f977..4fff7479b1 100644 --- a/sqflite/lib/src/sentry_sqflite_database_factory.dart +++ b/sqflite/lib/src/sentry_sqflite_database_factory.dart @@ -64,6 +64,10 @@ class SentrySqfliteDatabaseFactory with SqfliteDatabaseFactoryMixin { description: 'Open DB: $path', ); + span?.origin = + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseFactory; + try { final database = await databaseFactory.openDatabase(path, options: options); diff --git a/sqflite/test/mocks/mocks.mocks.dart b/sqflite/test/mocks/mocks.mocks.dart index 5af57a4e2b..582663e5f9 100644 --- a/sqflite/test/mocks/mocks.mocks.dart +++ b/sqflite/test/mocks/mocks.mocks.dart @@ -1,13 +1,13 @@ -// Mocks generated by Mockito 5.3.2 from annotations +// Mocks generated by Mockito 5.4.0 from annotations // in sentry_sqflite/test/mocks/mocks.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i5; +import 'dart:async' as _i4; import 'package:mockito/mockito.dart' as _i1; import 'package:sentry/sentry.dart' as _i2; -import 'package:sentry/src/sentry_tracer.dart' as _i4; +import 'package:sentry/src/sentry_tracer.dart' as _i5; import 'package:sqflite_common/sql.dart' as _i6; import 'package:sqflite_common/sqlite_api.dart' as _i3; @@ -76,8 +76,8 @@ class _FakeDatabase_4 extends _i1.SmartFake implements _i3.Database { ); } -class _FakeQueryCursor_5 extends _i1.SmartFake implements _i3.QueryCursor { - _FakeQueryCursor_5( +class _FakeFuture_5 extends _i1.SmartFake implements _i4.Future { + _FakeFuture_5( Object parent, Invocation parentInvocation, ) : super( @@ -86,8 +86,8 @@ class _FakeQueryCursor_5 extends _i1.SmartFake implements _i3.QueryCursor { ); } -class _FakeBatch_6 extends _i1.SmartFake implements _i3.Batch { - _FakeBatch_6( +class _FakeQueryCursor_6 extends _i1.SmartFake implements _i3.QueryCursor { + _FakeQueryCursor_6( Object parent, Invocation parentInvocation, ) : super( @@ -96,8 +96,8 @@ class _FakeBatch_6 extends _i1.SmartFake implements _i3.Batch { ); } -class _FakeSentryOptions_7 extends _i1.SmartFake implements _i2.SentryOptions { - _FakeSentryOptions_7( +class _FakeBatch_7 extends _i1.SmartFake implements _i3.Batch { + _FakeBatch_7( Object parent, Invocation parentInvocation, ) : super( @@ -106,8 +106,8 @@ class _FakeSentryOptions_7 extends _i1.SmartFake implements _i2.SentryOptions { ); } -class _FakeSentryId_8 extends _i1.SmartFake implements _i2.SentryId { - _FakeSentryId_8( +class _FakeSentryOptions_8 extends _i1.SmartFake implements _i2.SentryOptions { + _FakeSentryOptions_8( Object parent, Invocation parentInvocation, ) : super( @@ -116,8 +116,18 @@ class _FakeSentryId_8 extends _i1.SmartFake implements _i2.SentryId { ); } -class _FakeHub_9 extends _i1.SmartFake implements _i2.Hub { - _FakeHub_9( +class _FakeSentryId_9 extends _i1.SmartFake implements _i2.SentryId { + _FakeSentryId_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeHub_10 extends _i1.SmartFake implements _i2.Hub { + _FakeHub_10( Object parent, Invocation parentInvocation, ) : super( @@ -129,8 +139,8 @@ class _FakeHub_9 extends _i1.SmartFake implements _i2.Hub { /// A class which mocks [SentryTracer]. /// /// See the documentation for Mockito's code generation for more information. -/// ignore: invalid_use_of_internal_member -class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer { +// ignore: invalid_use_of_internal_member +class MockSentryTracer extends _i1.Mock implements _i5.SentryTracer { MockSentryTracer() { _i1.throwOnMissingStub(this); } @@ -173,6 +183,14 @@ class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer { ), ) as _i2.SentrySpanContext); @override + set origin(String? origin) => super.noSuchMethod( + Invocation.setter( + #origin, + origin, + ), + returnValueForMissingStub: null, + ); + @override DateTime get startTimestamp => (super.noSuchMethod( Invocation.getter(#startTimestamp), returnValue: _FakeDateTime_1( @@ -222,7 +240,7 @@ class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer { returnValue: {}, ) as Map); @override - _i5.Future finish({ + _i4.Future finish({ _i2.SpanStatus? status, DateTime? endTimestamp, }) => @@ -235,9 +253,9 @@ class MockSentryTracer extends _i1.Mock implements _i4.SentryTracer { #endTimestamp: endTimestamp, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override void removeData(String? key) => super.noSuchMethod( Invocation.method( @@ -400,7 +418,7 @@ class MockBatch extends _i1.Mock implements _i3.Batch { returnValue: 0, ) as int); @override - _i5.Future> commit({ + _i4.Future> commit({ bool? exclusive, bool? noResult, bool? continueOnError, @@ -415,10 +433,10 @@ class MockBatch extends _i1.Mock implements _i3.Batch { #continueOnError: continueOnError, }, ), - returnValue: _i5.Future>.value([]), - ) as _i5.Future>); + returnValue: _i4.Future>.value([]), + ) as _i4.Future>); @override - _i5.Future> apply({ + _i4.Future> apply({ bool? noResult, bool? continueOnError, }) => @@ -431,8 +449,8 @@ class MockBatch extends _i1.Mock implements _i3.Batch { #continueOnError: continueOnError, }, ), - returnValue: _i5.Future>.value([]), - ) as _i5.Future>); + returnValue: _i4.Future>.value([]), + ) as _i4.Future>); @override void rawInsert( String? sql, [ @@ -629,17 +647,17 @@ class MockDatabase extends _i1.Mock implements _i3.Database { ), ) as _i3.Database); @override - _i5.Future close() => (super.noSuchMethod( + _i4.Future close() => (super.noSuchMethod( Invocation.method( #close, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future transaction( - _i5.Future Function(_i3.Transaction)? action, { + _i4.Future transaction( + _i4.Future Function(_i3.Transaction)? action, { bool? exclusive, }) => (super.noSuchMethod( @@ -648,10 +666,17 @@ class MockDatabase extends _i1.Mock implements _i3.Database { [action], {#exclusive: exclusive}, ), - returnValue: _i5.Future.value(null), - ) as _i5.Future); + returnValue: _FakeFuture_5( + this, + Invocation.method( + #transaction, + [action], + {#exclusive: exclusive}, + ), + ), + ) as _i4.Future); @override - _i5.Future devInvokeMethod( + _i4.Future devInvokeMethod( String? method, [ Object? arguments, ]) => @@ -663,10 +688,19 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future.value(null), - ) as _i5.Future); + returnValue: _FakeFuture_5( + this, + Invocation.method( + #devInvokeMethod, + [ + method, + arguments, + ], + ), + ), + ) as _i4.Future); @override - _i5.Future devInvokeSqlMethod( + _i4.Future devInvokeSqlMethod( String? method, String? sql, [ List? arguments, @@ -680,10 +714,20 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future.value(null), - ) as _i5.Future); + returnValue: _FakeFuture_5( + this, + Invocation.method( + #devInvokeSqlMethod, + [ + method, + sql, + arguments, + ], + ), + ), + ) as _i4.Future); @override - _i5.Future execute( + _i4.Future execute( String? sql, [ List? arguments, ]) => @@ -695,11 +739,11 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future rawInsert( + _i4.Future rawInsert( String? sql, [ List? arguments, ]) => @@ -711,10 +755,10 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future insert( + _i4.Future insert( String? table, Map? values, { String? nullColumnHack, @@ -732,10 +776,10 @@ class MockDatabase extends _i1.Mock implements _i3.Database { #conflictAlgorithm: conflictAlgorithm, }, ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future>> query( + _i4.Future>> query( String? table, { bool? distinct, List? columns, @@ -763,11 +807,11 @@ class MockDatabase extends _i1.Mock implements _i3.Database { #offset: offset, }, ), - returnValue: _i5.Future>>.value( + returnValue: _i4.Future>>.value( >[]), - ) as _i5.Future>>); + ) as _i4.Future>>); @override - _i5.Future>> rawQuery( + _i4.Future>> rawQuery( String? sql, [ List? arguments, ]) => @@ -779,11 +823,11 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future>>.value( + returnValue: _i4.Future>>.value( >[]), - ) as _i5.Future>>); + ) as _i4.Future>>); @override - _i5.Future<_i3.QueryCursor> rawQueryCursor( + _i4.Future<_i3.QueryCursor> rawQueryCursor( String? sql, List? arguments, { int? bufferSize, @@ -797,7 +841,7 @@ class MockDatabase extends _i1.Mock implements _i3.Database { ], {#bufferSize: bufferSize}, ), - returnValue: _i5.Future<_i3.QueryCursor>.value(_FakeQueryCursor_5( + returnValue: _i4.Future<_i3.QueryCursor>.value(_FakeQueryCursor_6( this, Invocation.method( #rawQueryCursor, @@ -808,9 +852,9 @@ class MockDatabase extends _i1.Mock implements _i3.Database { {#bufferSize: bufferSize}, ), )), - ) as _i5.Future<_i3.QueryCursor>); + ) as _i4.Future<_i3.QueryCursor>); @override - _i5.Future<_i3.QueryCursor> queryCursor( + _i4.Future<_i3.QueryCursor> queryCursor( String? table, { bool? distinct, List? columns, @@ -840,7 +884,7 @@ class MockDatabase extends _i1.Mock implements _i3.Database { #bufferSize: bufferSize, }, ), - returnValue: _i5.Future<_i3.QueryCursor>.value(_FakeQueryCursor_5( + returnValue: _i4.Future<_i3.QueryCursor>.value(_FakeQueryCursor_6( this, Invocation.method( #queryCursor, @@ -859,9 +903,9 @@ class MockDatabase extends _i1.Mock implements _i3.Database { }, ), )), - ) as _i5.Future<_i3.QueryCursor>); + ) as _i4.Future<_i3.QueryCursor>); @override - _i5.Future rawUpdate( + _i4.Future rawUpdate( String? sql, [ List? arguments, ]) => @@ -873,10 +917,10 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future update( + _i4.Future update( String? table, Map? values, { String? where, @@ -896,10 +940,10 @@ class MockDatabase extends _i1.Mock implements _i3.Database { #conflictAlgorithm: conflictAlgorithm, }, ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future rawDelete( + _i4.Future rawDelete( String? sql, [ List? arguments, ]) => @@ -911,10 +955,10 @@ class MockDatabase extends _i1.Mock implements _i3.Database { arguments, ], ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future delete( + _i4.Future delete( String? table, { String? where, List? whereArgs, @@ -928,15 +972,15 @@ class MockDatabase extends _i1.Mock implements _i3.Database { #whereArgs: whereArgs, }, ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override _i3.Batch batch() => (super.noSuchMethod( Invocation.method( #batch, [], ), - returnValue: _FakeBatch_6( + returnValue: _FakeBatch_7( this, Invocation.method( #batch, @@ -963,7 +1007,7 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { ), ) as _i3.Database); @override - _i5.Future execute( + _i4.Future execute( String? sql, [ List? arguments, ]) => @@ -975,11 +1019,11 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { arguments, ], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future rawInsert( + _i4.Future rawInsert( String? sql, [ List? arguments, ]) => @@ -991,10 +1035,10 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { arguments, ], ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future insert( + _i4.Future insert( String? table, Map? values, { String? nullColumnHack, @@ -1012,10 +1056,10 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { #conflictAlgorithm: conflictAlgorithm, }, ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future>> query( + _i4.Future>> query( String? table, { bool? distinct, List? columns, @@ -1043,11 +1087,11 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { #offset: offset, }, ), - returnValue: _i5.Future>>.value( + returnValue: _i4.Future>>.value( >[]), - ) as _i5.Future>>); + ) as _i4.Future>>); @override - _i5.Future>> rawQuery( + _i4.Future>> rawQuery( String? sql, [ List? arguments, ]) => @@ -1059,11 +1103,11 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { arguments, ], ), - returnValue: _i5.Future>>.value( + returnValue: _i4.Future>>.value( >[]), - ) as _i5.Future>>); + ) as _i4.Future>>); @override - _i5.Future<_i3.QueryCursor> rawQueryCursor( + _i4.Future<_i3.QueryCursor> rawQueryCursor( String? sql, List? arguments, { int? bufferSize, @@ -1077,7 +1121,7 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { ], {#bufferSize: bufferSize}, ), - returnValue: _i5.Future<_i3.QueryCursor>.value(_FakeQueryCursor_5( + returnValue: _i4.Future<_i3.QueryCursor>.value(_FakeQueryCursor_6( this, Invocation.method( #rawQueryCursor, @@ -1088,9 +1132,9 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { {#bufferSize: bufferSize}, ), )), - ) as _i5.Future<_i3.QueryCursor>); + ) as _i4.Future<_i3.QueryCursor>); @override - _i5.Future<_i3.QueryCursor> queryCursor( + _i4.Future<_i3.QueryCursor> queryCursor( String? table, { bool? distinct, List? columns, @@ -1120,7 +1164,7 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { #bufferSize: bufferSize, }, ), - returnValue: _i5.Future<_i3.QueryCursor>.value(_FakeQueryCursor_5( + returnValue: _i4.Future<_i3.QueryCursor>.value(_FakeQueryCursor_6( this, Invocation.method( #queryCursor, @@ -1139,9 +1183,9 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { }, ), )), - ) as _i5.Future<_i3.QueryCursor>); + ) as _i4.Future<_i3.QueryCursor>); @override - _i5.Future rawUpdate( + _i4.Future rawUpdate( String? sql, [ List? arguments, ]) => @@ -1153,10 +1197,10 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { arguments, ], ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future update( + _i4.Future update( String? table, Map? values, { String? where, @@ -1176,10 +1220,10 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { #conflictAlgorithm: conflictAlgorithm, }, ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future rawDelete( + _i4.Future rawDelete( String? sql, [ List? arguments, ]) => @@ -1191,10 +1235,10 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { arguments, ], ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override - _i5.Future delete( + _i4.Future delete( String? table, { String? where, List? whereArgs, @@ -1208,15 +1252,15 @@ class MockDatabaseExecutor extends _i1.Mock implements _i3.DatabaseExecutor { #whereArgs: whereArgs, }, ), - returnValue: _i5.Future.value(0), - ) as _i5.Future); + returnValue: _i4.Future.value(0), + ) as _i4.Future); @override _i3.Batch batch() => (super.noSuchMethod( Invocation.method( #batch, [], ), - returnValue: _FakeBatch_6( + returnValue: _FakeBatch_7( this, Invocation.method( #batch, @@ -1237,7 +1281,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { @override _i2.SentryOptions get options => (super.noSuchMethod( Invocation.getter(#options), - returnValue: _FakeSentryOptions_7( + returnValue: _FakeSentryOptions_8( this, Invocation.getter(#options), ), @@ -1250,13 +1294,13 @@ class MockHub extends _i1.Mock implements _i2.Hub { @override _i2.SentryId get lastEventId => (super.noSuchMethod( Invocation.getter(#lastEventId), - returnValue: _FakeSentryId_8( + returnValue: _FakeSentryId_9( this, Invocation.getter(#lastEventId), ), ) as _i2.SentryId); @override - _i5.Future<_i2.SentryId> captureEvent( + _i4.Future<_i2.SentryId> captureEvent( _i2.SentryEvent? event, { dynamic stackTrace, _i2.Hint? hint, @@ -1272,7 +1316,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i5.Future<_i2.SentryId>.value(_FakeSentryId_8( + returnValue: _i4.Future<_i2.SentryId>.value(_FakeSentryId_9( this, Invocation.method( #captureEvent, @@ -1284,9 +1328,9 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i5.Future<_i2.SentryId>); + ) as _i4.Future<_i2.SentryId>); @override - _i5.Future<_i2.SentryId> captureException( + _i4.Future<_i2.SentryId> captureException( dynamic throwable, { dynamic stackTrace, _i2.Hint? hint, @@ -1302,7 +1346,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i5.Future<_i2.SentryId>.value(_FakeSentryId_8( + returnValue: _i4.Future<_i2.SentryId>.value(_FakeSentryId_9( this, Invocation.method( #captureException, @@ -1314,9 +1358,9 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i5.Future<_i2.SentryId>); + ) as _i4.Future<_i2.SentryId>); @override - _i5.Future<_i2.SentryId> captureMessage( + _i4.Future<_i2.SentryId> captureMessage( String? message, { _i2.SentryLevel? level, String? template, @@ -1336,7 +1380,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #withScope: withScope, }, ), - returnValue: _i5.Future<_i2.SentryId>.value(_FakeSentryId_8( + returnValue: _i4.Future<_i2.SentryId>.value(_FakeSentryId_9( this, Invocation.method( #captureMessage, @@ -1350,19 +1394,19 @@ class MockHub extends _i1.Mock implements _i2.Hub { }, ), )), - ) as _i5.Future<_i2.SentryId>); + ) as _i4.Future<_i2.SentryId>); @override - _i5.Future captureUserFeedback(_i2.SentryUserFeedback? userFeedback) => + _i4.Future captureUserFeedback(_i2.SentryUserFeedback? userFeedback) => (super.noSuchMethod( Invocation.method( #captureUserFeedback, [userFeedback], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future addBreadcrumb( + _i4.Future addBreadcrumb( _i2.Breadcrumb? crumb, { _i2.Hint? hint, }) => @@ -1372,9 +1416,9 @@ class MockHub extends _i1.Mock implements _i2.Hub { [crumb], {#hint: hint}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override void bindClient(_i2.SentryClient? client) => super.noSuchMethod( Invocation.method( @@ -1389,7 +1433,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { #clone, [], ), - returnValue: _FakeHub_9( + returnValue: _FakeHub_10( this, Invocation.method( #clone, @@ -1398,20 +1442,20 @@ class MockHub extends _i1.Mock implements _i2.Hub { ), ) as _i2.Hub); @override - _i5.Future close() => (super.noSuchMethod( + _i4.Future close() => (super.noSuchMethod( Invocation.method( #close, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.FutureOr configureScope(_i2.ScopeCallback? callback) => + _i4.FutureOr configureScope(_i2.ScopeCallback? callback) => (super.noSuchMethod(Invocation.method( #configureScope, [callback], - )) as _i5.FutureOr); + )) as _i4.FutureOr); @override _i2.ISentrySpan startTransaction( String? name, @@ -1499,7 +1543,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { ), ) as _i2.ISentrySpan); @override - _i5.Future<_i2.SentryId> captureTransaction( + _i4.Future<_i2.SentryId> captureTransaction( _i2.SentryTransaction? transaction, { _i2.SentryTraceContextHeader? traceContext, }) => @@ -1509,7 +1553,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { [transaction], {#traceContext: traceContext}, ), - returnValue: _i5.Future<_i2.SentryId>.value(_FakeSentryId_8( + returnValue: _i4.Future<_i2.SentryId>.value(_FakeSentryId_9( this, Invocation.method( #captureTransaction, @@ -1517,7 +1561,7 @@ class MockHub extends _i1.Mock implements _i2.Hub { {#traceContext: traceContext}, ), )), - ) as _i5.Future<_i2.SentryId>); + ) as _i4.Future<_i2.SentryId>); @override void setSpanContext( dynamic throwable, diff --git a/sqflite/test/sentry_batch_test.dart b/sqflite/test/sentry_batch_test.dart index 4cea3cbf7b..e01aa4d5c7 100644 --- a/sqflite/test/sentry_batch_test.dart +++ b/sqflite/test/sentry_batch_test.dart @@ -60,6 +60,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.status, SpanStatus.ok()); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -74,6 +76,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.status, SpanStatus.ok()); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -92,6 +96,8 @@ void main() { span.context.description, 'INSERT INTO Product (title) VALUES (?)', ); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -110,6 +116,8 @@ void main() { span.context.description, 'INSERT INTO Product (title) VALUES (?)', ); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -125,6 +133,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'UPDATE Product SET title = ?'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -140,6 +150,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'UPDATE Product SET title = ?'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -155,6 +167,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'DELETE FROM Product'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -170,6 +184,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'DELETE FROM Product'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -185,6 +201,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'DELETE FROM Product'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -200,6 +218,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'SELECT * FROM Product'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -215,6 +235,8 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'SELECT * FROM Product'); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -235,6 +257,8 @@ SELECT * FROM Product'''; expect(span.context.operation, 'db'); expect(span.context.description, desc); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -255,6 +279,8 @@ SELECT * FROM Product'''; expect(span.context.operation, 'db'); expect(span.context.description, desc); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); await db.close(); }); @@ -286,6 +312,8 @@ SELECT * FROM Product'''; final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); }); test('apply sets span to internal error if its thrown', () async { @@ -300,6 +328,8 @@ SELECT * FROM Product'''; final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteBatch); }); }); } diff --git a/sqflite/test/sentry_database_test.dart b/sqflite/test/sentry_database_test.dart index 3ec80568fc..3a76d8066e 100644 --- a/sqflite/test/sentry_database_test.dart +++ b/sqflite/test/sentry_database_test.dart @@ -67,6 +67,11 @@ void main() { expect(span.context.operation, 'db'); expect(span.context.description, 'Close DB: $inMemoryDatabasePath'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabase, + ); }); test('creates transaction span', () async { @@ -79,6 +84,11 @@ void main() { expect(span.context.operation, 'db.sql.transaction'); expect(span.context.description, 'Transaction DB: $inMemoryDatabasePath'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabase, + ); await db.close(); }); @@ -100,6 +110,12 @@ void main() { expect(insertSpan.context.parentSpanId, trSpan.context.spanId); expect(insertSpan.status, SpanStatus.ok()); + expect( + insertSpan.origin, + // ignore: invalid_use_of_internal_member, + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -142,6 +158,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabase, + ); }); test('transaction sets span to internal error', () async { @@ -158,6 +180,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabase, + ); }); }); @@ -185,6 +213,12 @@ void main() { expect(span.context.description, 'DELETE FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -198,6 +232,12 @@ void main() { expect(span.context.description, 'DELETE FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -214,6 +254,12 @@ void main() { ); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -227,6 +273,12 @@ void main() { expect(span.context.description, 'SELECT * FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -240,6 +292,12 @@ void main() { expect(span.context.description, 'SELECT * FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -253,6 +311,12 @@ void main() { expect(span.context.description, 'DELETE FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -270,6 +334,12 @@ void main() { ); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -283,6 +353,12 @@ void main() { expect(span.context.description, 'SELECT * FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -296,6 +372,12 @@ void main() { expect(span.context.description, 'SELECT * FROM Product'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -309,6 +391,12 @@ void main() { expect(span.context.description, 'UPDATE Product SET title = ?'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -322,6 +410,12 @@ void main() { expect(span.context.description, 'UPDATE Product SET title = ?'); expect(span.status, SpanStatus.ok()); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); + await db.close(); }); @@ -353,6 +447,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('execute sets span to internal error', () async { @@ -368,6 +468,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('insert sets span to internal error', () async { @@ -384,6 +490,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('query sets span to internal error', () async { @@ -399,6 +511,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('query cursor sets span to internal error', () async { @@ -414,6 +532,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('raw delete sets span to internal error', () async { @@ -429,6 +553,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('raw insert sets span to internal error', () async { @@ -444,6 +574,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('raw query sets span to internal error', () async { @@ -459,6 +595,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('raw query cursor sets span to internal error', () async { @@ -475,6 +617,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('raw update sets span to internal error', () async { @@ -490,6 +638,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); test('update sets span to internal error', () async { @@ -506,6 +660,12 @@ void main() { final span = fixture.tracer.children.last; expect(span.throwable, fixture.exception); expect(span.status, SpanStatus.internalError()); + + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseExecutor, + ); }); }); } diff --git a/sqflite/test/sentry_sqflite_database_factory_dart_test.dart b/sqflite/test/sentry_sqflite_database_factory_dart_test.dart index 1926ad68d5..61f8aaa9ca 100644 --- a/sqflite/test/sentry_sqflite_database_factory_dart_test.dart +++ b/sqflite/test/sentry_sqflite_database_factory_dart_test.dart @@ -59,7 +59,13 @@ void main() { final span = fixture.tracer.children.last; expect(span.context.operation, 'db'); expect(span.context.description, 'Open DB: $inMemoryDatabasePath'); + expect(span.context.description, 'Open DB: $inMemoryDatabasePath'); + expect( + span.origin, + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbSqfliteDatabaseFactory, + ); await db.close(); }); }); diff --git a/sqflite/test/sentry_sqflite_test.dart b/sqflite/test/sentry_sqflite_test.dart index 5bd099a063..54ff24232d 100644 --- a/sqflite/test/sentry_sqflite_test.dart +++ b/sqflite/test/sentry_sqflite_test.dart @@ -31,6 +31,10 @@ void main() { databaseFactory = databaseFactoryFfi; }); + tearDown(() { + databaseFactory = sqfliteDatabaseFactoryDefault; + }); + test('returns wrapped data base if performance enabled', () async { final db = await openDatabaseWithSentry(inMemoryDatabasePath, hub: fixture.hub); @@ -82,8 +86,19 @@ void main() { await db.close(); }); - tearDown(() { - databaseFactory = sqfliteDatabaseFactoryDefault; + test('creates db open span', () async { + final db = + await openDatabaseWithSentry(inMemoryDatabasePath, hub: fixture.hub); + + final span = fixture.tracer.children.last; + + expect(span.context.operation, SentryDatabase.dbOp); + expect(span.context.description, 'Open DB: $inMemoryDatabasePath'); + expect(span.status, SpanStatus.ok()); + // ignore: invalid_use_of_internal_member + expect(span.origin, SentryTraceOrigins.autoDbSqfliteOpenDatabase); + + await db.close(); }); }); }