forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground_resource_telemetry_test.dart
More file actions
135 lines (125 loc) · 4.57 KB
/
Copy pathbackground_resource_telemetry_test.dart
File metadata and controls
135 lines (125 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import 'package:flutter_test/flutter_test.dart';
import 'package:omi/utils/analytics/background_resource_telemetry.dart';
void main() {
const startSnapshot = BackgroundResourceSnapshot(
bleBytesReceived: 100,
websocketBytesSent: 50,
recordingState: 'deviceRecord',
deviceConnected: true,
deviceType: 'omi',
batchModeEnabled: false,
diagnosticsDeviceId: 'device-1',
);
test('emits one bounded summary with resource deltas after a real background session', () async {
var now = DateTime.utc(2026, 8, 19, 12);
String? emittedName;
Map<String, dynamic>? emittedProperties;
final telemetry = BackgroundResourceTelemetry(
emit: (name, properties) {
emittedName = name;
emittedProperties = properties;
},
now: () => now,
sessionIdFactory: () => 'session-1',
);
telemetry.onPaused(startSnapshot);
// Duplicate lifecycle callbacks must not replace the original baseline.
now = now.add(const Duration(seconds: 30));
telemetry.onPaused(startSnapshot);
now = now.add(const Duration(seconds: 90));
await telemetry.onResumed(
(_, start) async {
expect(start.diagnosticsDeviceId, 'device-1');
return const BackgroundResourceSnapshot(
bleBytesReceived: 1300,
websocketBytesSent: 650,
recordingState: 'deviceRecord',
deviceConnected: true,
deviceType: 'omi',
batchModeEnabled: false,
foregroundTaskRunning: false,
backgroundDisconnectCount: 3,
connectionTimeoutCount: 2,
failToConnectCount: 1,
reconnectCount: 2,
maxReconnectDurationMs: 4200,
reconnectionCountTotal: 11,
failToConnectCountTotal: 5,
bleHistorySaturated: true,
nativeBackgroundBytesConsumed: 4200,
nativeBackgroundPacketsConsumed: 42,
);
},
);
expect(emittedName, BackgroundResourceTelemetry.eventName);
expect(emittedProperties, {
'background_session_id': 'session-1',
'background_duration_seconds': 120,
'start_recording_state': 'deviceRecord',
'end_recording_state': 'deviceRecord',
'start_device_connected': true,
'end_device_connected': true,
'start_device_type': 'omi',
'end_device_type': 'omi',
'batch_mode_enabled': false,
'ble_bytes_received': 1200,
'websocket_bytes_sent': 600,
'ble_receive_bytes_per_second': 10,
'websocket_send_bytes_per_second': 5,
'foreground_task_running_on_resume': false,
'background_disconnect_count': 3,
'connection_timeout_count': 2,
'fail_to_connect_count': 1,
'reconnect_count': 2,
'max_reconnect_duration_ms': 4200,
'reconnection_count_total': 11,
'fail_to_connect_count_total': 5,
'ble_history_saturated': true,
'native_background_bytes_consumed': 4200,
'native_background_packets_consumed': 42,
});
});
test('suppresses short sessions and clamps counters that reset', () async {
var now = DateTime.utc(2026, 8, 19, 12);
final events = <Map<String, dynamic>>[];
final telemetry = BackgroundResourceTelemetry(
emit: (_, properties) => events.add(properties),
now: () => now,
sessionIdFactory: () => 'session-2',
);
telemetry.onPaused(startSnapshot);
now = now.add(const Duration(seconds: 59));
await telemetry.onResumed((_, __) async => startSnapshot);
expect(events, isEmpty);
telemetry.onPaused(startSnapshot);
now = now.add(const Duration(minutes: 1));
await telemetry.onResumed(
(_, __) async => const BackgroundResourceSnapshot(
bleBytesReceived: 0,
websocketBytesSent: 0,
recordingState: 'stop',
deviceConnected: false,
deviceType: 'none',
batchModeEnabled: false,
),
);
expect(events.single['ble_bytes_received'], 0);
expect(events.single['websocket_bytes_sent'], 0);
});
test('snapshot and emitter failures are fail-open and session state recovers', () async {
var now = DateTime.utc(2026, 8, 19, 12);
final telemetry = BackgroundResourceTelemetry(
emit: (_, __) => throw StateError('analytics unavailable'),
now: () => now,
);
telemetry.onPaused(startSnapshot);
now = now.add(const Duration(minutes: 2));
await expectLater(
telemetry.onResumed((_, __) async => throw StateError('snapshot unavailable')),
completes,
);
telemetry.onPaused(startSnapshot);
now = now.add(const Duration(minutes: 2));
await expectLater(telemetry.onResumed((_, __) async => startSnapshot), completes);
});
}