Skip to content

Commit d0ac278

Browse files
committed
add tracer tests
1 parent 9d13808 commit d0ac278

11 files changed

+207
-125
lines changed

dart/lib/src/protocol/sentry_span.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,5 +199,5 @@ class SentrySpan extends ISentrySpan {
199199
SentryTraceContextHeader? traceContext() => _tracer.traceContext();
200200

201201
@override
202-
void scheduleFinish() {}
202+
void scheduleFinish() => _tracer.scheduleFinish();
203203
}

dart/lib/src/sentry_tracer.dart

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class SentryTracer extends ISentrySpan {
1919

2020
Timer? _autoFinishAfterTimer;
2121
Duration? _autoFinishAfter;
22+
23+
@visibleForTesting
24+
Timer? get autoFinishAfterTimer => _autoFinishAfterTimer;
25+
2226
Function(SentryTracer)? _onFinish;
2327
var _finishStatus = SentryTracerFinishStatus.notFinishing();
2428
late final bool _trimEnd;

dart/test/protocol/breadcrumb_test.dart

+107-74
Original file line numberDiff line numberDiff line change
@@ -79,86 +79,119 @@ void main() {
7979
});
8080
});
8181

82-
test('Breadcrumb http ctor', () {
83-
final breadcrumb = Breadcrumb.http(
84-
url: Uri.parse('https://example.org'),
85-
method: 'GET',
86-
level: SentryLevel.fatal,
87-
reason: 'OK',
88-
statusCode: 200,
89-
requestDuration: Duration.zero,
90-
timestamp: DateTime.now(),
91-
requestBodySize: 2,
92-
responseBodySize: 3,
93-
);
94-
final json = breadcrumb.toJson();
95-
96-
expect(json, {
97-
'timestamp': formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
98-
'category': 'http',
99-
'data': {
100-
'url': 'https://example.org',
101-
'method': 'GET',
102-
'status_code': 200,
103-
'reason': 'OK',
104-
'duration': '0:00:00.000000',
105-
'request_body_size': 2,
106-
'response_body_size': 3,
107-
},
108-
'level': 'fatal',
109-
'type': 'http',
82+
group('ctor', () {
83+
test('Breadcrumb http', () {
84+
final breadcrumb = Breadcrumb.http(
85+
url: Uri.parse('https://example.org'),
86+
method: 'GET',
87+
level: SentryLevel.fatal,
88+
reason: 'OK',
89+
statusCode: 200,
90+
requestDuration: Duration.zero,
91+
timestamp: DateTime.now(),
92+
requestBodySize: 2,
93+
responseBodySize: 3,
94+
);
95+
final json = breadcrumb.toJson();
96+
97+
expect(json, {
98+
'timestamp':
99+
formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
100+
'category': 'http',
101+
'data': {
102+
'url': 'https://example.org',
103+
'method': 'GET',
104+
'status_code': 200,
105+
'reason': 'OK',
106+
'duration': '0:00:00.000000',
107+
'request_body_size': 2,
108+
'response_body_size': 3,
109+
},
110+
'level': 'fatal',
111+
'type': 'http',
112+
});
110113
});
111-
});
112114

113-
test('Minimal Breadcrumb http ctor', () {
114-
final breadcrumb = Breadcrumb.http(
115-
url: Uri.parse('https://example.org'),
116-
method: 'GET',
117-
);
118-
final json = breadcrumb.toJson();
119-
120-
expect(json, {
121-
'timestamp': formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
122-
'category': 'http',
123-
'data': {
124-
'url': 'https://example.org',
125-
'method': 'GET',
126-
},
127-
'level': 'info',
128-
'type': 'http',
115+
test('Minimal Breadcrumb http', () {
116+
final breadcrumb = Breadcrumb.http(
117+
url: Uri.parse('https://example.org'),
118+
method: 'GET',
119+
);
120+
final json = breadcrumb.toJson();
121+
122+
expect(json, {
123+
'timestamp':
124+
formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
125+
'category': 'http',
126+
'data': {
127+
'url': 'https://example.org',
128+
'method': 'GET',
129+
},
130+
'level': 'info',
131+
'type': 'http',
132+
});
129133
});
130-
});
131134

132-
test('Breadcrumb console ctor', () {
133-
final breadcrumb = Breadcrumb.console(
134-
message: 'Foo Bar',
135-
);
136-
final json = breadcrumb.toJson();
137-
138-
expect(json, {
139-
'message': 'Foo Bar',
140-
'timestamp': formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
141-
'category': 'console',
142-
'type': 'debug',
143-
'level': 'info',
135+
test('Breadcrumb console', () {
136+
final breadcrumb = Breadcrumb.console(
137+
message: 'Foo Bar',
138+
);
139+
final json = breadcrumb.toJson();
140+
141+
expect(json, {
142+
'message': 'Foo Bar',
143+
'timestamp':
144+
formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
145+
'category': 'console',
146+
'type': 'debug',
147+
'level': 'info',
148+
});
144149
});
145-
});
146150

147-
test('extensive Breadcrumb console ctor', () {
148-
final breadcrumb = Breadcrumb.console(
149-
message: 'Foo Bar',
150-
level: SentryLevel.error,
151-
data: {'foo': 'bar'},
152-
);
153-
final json = breadcrumb.toJson();
154-
155-
expect(json, {
156-
'message': 'Foo Bar',
157-
'timestamp': formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
158-
'category': 'console',
159-
'type': 'debug',
160-
'level': 'error',
161-
'data': {'foo': 'bar'},
151+
test('extensive Breadcrumb console', () {
152+
final breadcrumb = Breadcrumb.console(
153+
message: 'Foo Bar',
154+
level: SentryLevel.error,
155+
data: {'foo': 'bar'},
156+
);
157+
final json = breadcrumb.toJson();
158+
159+
expect(json, {
160+
'message': 'Foo Bar',
161+
'timestamp':
162+
formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp),
163+
'category': 'console',
164+
'type': 'debug',
165+
'level': 'error',
166+
'data': {'foo': 'bar'},
167+
});
168+
});
169+
170+
test('extensive Breadcrumb user interaction', () {
171+
final time = DateTime.now().toUtc();
172+
final breadcrumb = Breadcrumb.userInteraction(
173+
message: 'Foo Bar',
174+
level: SentryLevel.error,
175+
timestamp: time,
176+
data: {'foo': 'bar'},
177+
subCategory: 'click',
178+
viewId: 'foo',
179+
viewClass: 'bar',
180+
);
181+
final json = breadcrumb.toJson();
182+
183+
expect(json, {
184+
'message': 'Foo Bar',
185+
'timestamp': formatDateAsIso8601WithMillisPrecision(time),
186+
'category': 'ui.click',
187+
'type': 'user',
188+
'level': 'error',
189+
'data': {
190+
'foo': 'bar',
191+
'view.id': 'foo',
192+
'view.class': 'bar',
193+
},
194+
});
162195
});
163196
});
164197
}

dart/test/sentry_options_test.dart

+6
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,10 @@ void main() {
9595

9696
expect(options.tracePropagationTargets, ['.*']);
9797
});
98+
99+
test('SentryOptions has default idleTimeout', () {
100+
final options = SentryOptions.empty();
101+
102+
expect(options.idleTimeout?.inSeconds, Duration(seconds: 3).inSeconds);
103+
});
98104
}

dart/test/sentry_span_test.dart

+19-5
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@ void main() {
244244

245245
expect(sut.endTimestamp, endTimestamp);
246246
});
247+
248+
test('child span reschedule finish timer', () async {
249+
final sut = fixture.getSut(autoFinishAfter: Duration(seconds: 5));
250+
251+
final currentTimer = fixture.tracer.autoFinishAfterTimer!;
252+
253+
sut.scheduleFinish();
254+
255+
final newTimer = fixture.tracer.autoFinishAfterTimer!;
256+
257+
expect(currentTimer, isNot(equals(newTimer)));
258+
});
247259
}
248260

249261
class Fixture {
@@ -254,11 +266,13 @@ class Fixture {
254266
late SentryTracer tracer;
255267
final hub = MockHub();
256268

257-
SentrySpan getSut(
258-
{DateTime? startTimestamp,
259-
bool? sampled = true,
260-
Function({DateTime? endTimestamp})? finishedCallback}) {
261-
tracer = SentryTracer(context, hub);
269+
SentrySpan getSut({
270+
DateTime? startTimestamp,
271+
bool? sampled = true,
272+
Function({DateTime? endTimestamp})? finishedCallback,
273+
Duration? autoFinishAfter,
274+
}) {
275+
tracer = SentryTracer(context, hub, autoFinishAfter: autoFinishAfter);
262276

263277
return SentrySpan(
264278
tracer,

dart/test/sentry_tracer_test.dart

+55-28
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,32 @@ void main() {
269269
expect(sut.finished, true);
270270
});
271271

272+
test('tracer reschedule finish timer', () async {
273+
final sut = fixture.getSut(autoFinishAfter: Duration(milliseconds: 200));
274+
275+
final currentTimer = sut.autoFinishAfterTimer!;
276+
277+
sut.scheduleFinish();
278+
279+
final newTimer = sut.autoFinishAfterTimer!;
280+
281+
expect(currentTimer, isNot(equals(newTimer)));
282+
});
283+
284+
test('tracer do not reschedule if finished', () async {
285+
final sut = fixture.getSut(autoFinishAfter: Duration(milliseconds: 200));
286+
287+
final currentTimer = sut.autoFinishAfterTimer!;
288+
289+
await sut.finish();
290+
291+
sut.scheduleFinish();
292+
293+
final newTimer = sut.autoFinishAfterTimer!;
294+
295+
expect(currentTimer, newTimer);
296+
});
297+
272298
test('tracer finish needs child to finish', () async {
273299
final sut = fixture.getSut(waitForChildren: true);
274300

@@ -374,6 +400,14 @@ void main() {
374400
expect(sut.startChild('child3'), isA<NoOpSentrySpan>());
375401
});
376402

403+
test('do not capture idle transaction without children', () async {
404+
final sut = fixture.getSut(autoFinishAfter: Duration(milliseconds: 200));
405+
406+
await sut.finish();
407+
408+
expect(fixture.hub.captureTransactionCalls.isEmpty, true);
409+
});
410+
377411
test('tracer sets measurement', () async {
378412
final sut = fixture.getSut();
379413

@@ -407,24 +441,15 @@ void main() {
407441
});
408442

409443
group('$SentryBaggageHeader', () {
410-
final _options = SentryOptions(dsn: fakeDsn)
411-
..release = 'release'
412-
..environment = 'environment';
413-
444+
late Fixture _fixture;
414445
late Hub _hub;
415446

416-
final _client = MockSentryClient();
417-
418-
final _user = SentryUser(
419-
id: 'id',
420-
segment: 'segment',
421-
);
422-
423447
setUp(() async {
424-
_hub = Hub(_options);
425-
_hub.configureScope((scope) => scope.setUser(_user));
448+
_fixture = Fixture();
449+
_hub = Hub(_fixture.options);
450+
_hub.configureScope((scope) => scope.setUser(_fixture.user));
426451

427-
_hub.bindClient(_client);
452+
_hub.bindClient(_fixture.client);
428453
});
429454

430455
SentryTracer getSut({SentryTracesSamplingDecision? samplingDecision}) {
@@ -492,24 +517,15 @@ void main() {
492517
});
493518

494519
group('$SentryTraceContextHeader', () {
495-
final _options = SentryOptions(dsn: fakeDsn)
496-
..release = 'release'
497-
..environment = 'environment';
498-
520+
late Fixture _fixture;
499521
late Hub _hub;
500522

501-
final _client = MockSentryClient();
502-
503-
final _user = SentryUser(
504-
id: 'id',
505-
segment: 'segment',
506-
);
507-
508523
setUp(() async {
509-
_hub = Hub(_options);
510-
_hub.configureScope((scope) => scope.setUser(_user));
524+
_fixture = Fixture();
525+
_hub = Hub(_fixture.options);
526+
_hub.configureScope((scope) => scope.setUser(_fixture.user));
511527

512-
_hub.bindClient(_client);
528+
_hub.bindClient(_fixture.client);
513529
});
514530

515531
SentryTracer getSut({SentryTracesSamplingDecision? samplingDecision}) {
@@ -544,6 +560,17 @@ void main() {
544560
}
545561

546562
class Fixture {
563+
final options = SentryOptions(dsn: fakeDsn)
564+
..release = 'release'
565+
..environment = 'environment';
566+
567+
final client = MockSentryClient();
568+
569+
final user = SentryUser(
570+
id: 'id',
571+
segment: 'segment',
572+
);
573+
547574
final hub = MockHub();
548575

549576
SentryTracer getSut({

0 commit comments

Comments
 (0)