@webex/internal-plugin-metrics 3.12.0-next.4 → 3.12.0-next.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automated-user.js +19 -0
- package/dist/automated-user.js.map +1 -0
- package/dist/batcher.js +3 -0
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +638 -65
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +167 -76
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +16 -3
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js +4 -0
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +16 -6
- package/dist/new-metrics.js.map +1 -1
- package/dist/types/automated-user.d.ts +2 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +208 -5
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +67 -14
- package/dist/types/call-diagnostic/config.d.ts +4 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/metrics.types.d.ts +4 -2
- package/dist/types/new-metrics.d.ts +4 -0
- package/package.json +12 -11
- package/src/automated-user.ts +16 -0
- package/src/batcher.js +4 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +800 -73
- package/src/call-diagnostic/call-diagnostic-metrics.ts +101 -15
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
- package/src/call-diagnostic/config.ts +14 -0
- package/src/config.js +1 -0
- package/src/index.ts +5 -0
- package/src/metrics.types.ts +16 -3
- package/src/new-metrics.ts +12 -4
- package/test/unit/spec/automated-user.ts +43 -0
- package/test/unit/spec/batcher.js +43 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +14 -2
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1434 -303
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +852 -159
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
- package/test/unit/spec/new-metrics.ts +39 -2
- package/test/unit/spec/prelogin-metrics-batcher.ts +71 -36
|
@@ -5,11 +5,12 @@ import sinon from 'sinon';
|
|
|
5
5
|
describe('internal-plugin-metrics', () => {
|
|
6
6
|
describe('CallDiagnosticLatencies', () => {
|
|
7
7
|
let cdl: CallDiagnosticLatencies;
|
|
8
|
+
let clock: ReturnType<typeof sinon.useFakeTimers>;
|
|
8
9
|
var now = new Date();
|
|
9
10
|
|
|
10
11
|
beforeEach(() => {
|
|
11
12
|
sinon.createSandbox();
|
|
12
|
-
sinon.useFakeTimers(now.getTime());
|
|
13
|
+
clock = sinon.useFakeTimers(now.getTime());
|
|
13
14
|
const webex = {
|
|
14
15
|
meetings: {
|
|
15
16
|
getBasicMeetingInformation: (id: string) => {
|
|
@@ -51,17 +52,17 @@ describe('internal-plugin-metrics', () => {
|
|
|
51
52
|
|
|
52
53
|
it('should overwrite latency when accumulate is false', () => {
|
|
53
54
|
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
54
|
-
cdl.saveLatency('internal.client.pageJMT', 10, false);
|
|
55
|
+
cdl.saveLatency('internal.client.pageJMT', 10, {accumulate: false});
|
|
55
56
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
56
57
|
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
57
|
-
cdl.saveLatency('internal.client.pageJMT', 20, false);
|
|
58
|
+
cdl.saveLatency('internal.client.pageJMT', 20, {accumulate: false});
|
|
58
59
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
59
60
|
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
it('should save latency correctly when accumulate is true', () => {
|
|
63
64
|
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
64
|
-
cdl.saveLatency('internal.client.pageJMT', 10, true);
|
|
65
|
+
cdl.saveLatency('internal.client.pageJMT', 10, {accumulate: true});
|
|
65
66
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
66
67
|
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
67
68
|
});
|
|
@@ -71,11 +72,31 @@ describe('internal-plugin-metrics', () => {
|
|
|
71
72
|
cdl.saveLatency('internal.client.pageJMT', 10);
|
|
72
73
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
73
74
|
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
|
|
74
|
-
cdl.saveLatency('internal.client.pageJMT', 10, true);
|
|
75
|
+
cdl.saveLatency('internal.client.pageJMT', 10, {accumulate: true});
|
|
75
76
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
76
77
|
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
|
|
77
78
|
});
|
|
78
79
|
|
|
80
|
+
it('accumulates when accumulate is passed as the legacy boolean argument', () => {
|
|
81
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
82
|
+
// @ts-ignore - legacy boolean third argument from older (untyped) SDK/plugin consumers
|
|
83
|
+
cdl.saveLatency('internal.client.pageJMT', 10, true);
|
|
84
|
+
// @ts-ignore - legacy boolean third argument from older (untyped) SDK/plugin consumers
|
|
85
|
+
cdl.saveLatency('internal.client.pageJMT', 15, true);
|
|
86
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
87
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 25);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('overwrites when the legacy boolean argument is false', () => {
|
|
91
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
92
|
+
// @ts-ignore - legacy boolean third argument from older (untyped) SDK/plugin consumers
|
|
93
|
+
cdl.saveLatency('internal.client.pageJMT', 10, false);
|
|
94
|
+
// @ts-ignore - legacy boolean third argument from older (untyped) SDK/plugin consumers
|
|
95
|
+
cdl.saveLatency('internal.client.pageJMT', 15, false);
|
|
96
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
97
|
+
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 15);
|
|
98
|
+
});
|
|
99
|
+
|
|
79
100
|
it('should save only first timestamp correctly', () => {
|
|
80
101
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
81
102
|
cdl.saveFirstTimestampOnly('client.alert.displayed', 10);
|
|
@@ -108,11 +129,1174 @@ describe('internal-plugin-metrics', () => {
|
|
|
108
129
|
assert.deepEqual(cdl.latencyTimestamps.size, 2);
|
|
109
130
|
cdl.saveLatency('internal.api.fetch.intelligence.models', 42);
|
|
110
131
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
132
|
+
cdl.saveTimestamp({
|
|
133
|
+
key: 'internal.client.locus.sync.start',
|
|
134
|
+
value: 1,
|
|
135
|
+
options: {
|
|
136
|
+
meetingId: 'meeting-1',
|
|
137
|
+
dataSetName: 'main',
|
|
138
|
+
randomBackoffTime: 10,
|
|
139
|
+
trackingId: 'sync-tracking-id',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
assert.deepEqual(cdl.meetingLatencies.size, 1);
|
|
111
143
|
|
|
112
144
|
cdl.clearTimestamps();
|
|
113
145
|
|
|
114
146
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
115
147
|
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
148
|
+
assert.deepEqual(cdl.meetingLatencies.size, 0);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe('locus sync latencies', () => {
|
|
152
|
+
it('uses pending sync backoff latency when sync starts', () => {
|
|
153
|
+
cdl.saveLatency('internal.client.locus.sync.random.backoff', 10.4, {
|
|
154
|
+
meetingId: 'meeting-1',
|
|
155
|
+
dataSetName: 'main',
|
|
156
|
+
});
|
|
157
|
+
cdl.saveTimestamp({
|
|
158
|
+
key: 'internal.client.locus.sync.start',
|
|
159
|
+
value: 100,
|
|
160
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
161
|
+
});
|
|
162
|
+
cdl.saveTimestamp({
|
|
163
|
+
key: 'internal.client.locus.sync.request',
|
|
164
|
+
value: 110,
|
|
165
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
166
|
+
});
|
|
167
|
+
cdl.saveTimestamp({
|
|
168
|
+
key: 'internal.client.locus.sync.response',
|
|
169
|
+
value: 130,
|
|
170
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
171
|
+
});
|
|
172
|
+
cdl.saveTimestamp({
|
|
173
|
+
key: 'internal.client.locus.sync.message.received',
|
|
174
|
+
value: 140,
|
|
175
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
assert.deepEqual(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-id'), {
|
|
179
|
+
randomBackoffTime: 10,
|
|
180
|
+
hashtreePrepTime: 0,
|
|
181
|
+
hashtreeResponseTime: 0,
|
|
182
|
+
syncPrepTime: 10,
|
|
183
|
+
syncResponseTime: 20,
|
|
184
|
+
syncMessageReceiveTime: 30,
|
|
185
|
+
totalTime: 40,
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('calculates sync latency values from milestones', () => {
|
|
190
|
+
cdl.saveLatency('internal.client.locus.sync.random.backoff', 10.4, {
|
|
191
|
+
meetingId: 'meeting-1',
|
|
192
|
+
dataSetName: 'main',
|
|
193
|
+
});
|
|
194
|
+
cdl.saveTimestamp({
|
|
195
|
+
key: 'internal.client.locus.sync.start',
|
|
196
|
+
value: 100,
|
|
197
|
+
options: {
|
|
198
|
+
meetingId: 'meeting-1',
|
|
199
|
+
dataSetName: 'main',
|
|
200
|
+
trackingId: 'sync-tracking-id',
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
cdl.saveTimestamp({
|
|
204
|
+
key: 'internal.client.locus.hashtree.request',
|
|
205
|
+
value: 105,
|
|
206
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
207
|
+
});
|
|
208
|
+
cdl.saveTimestamp({
|
|
209
|
+
key: 'internal.client.locus.hashtree.response',
|
|
210
|
+
value: 125,
|
|
211
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
212
|
+
});
|
|
213
|
+
cdl.saveTimestamp({
|
|
214
|
+
key: 'internal.client.locus.sync.request',
|
|
215
|
+
value: 128,
|
|
216
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
217
|
+
});
|
|
218
|
+
cdl.saveTimestamp({
|
|
219
|
+
key: 'internal.client.locus.sync.response',
|
|
220
|
+
value: 143,
|
|
221
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
222
|
+
});
|
|
223
|
+
cdl.saveTimestamp({
|
|
224
|
+
key: 'internal.client.locus.sync.message.received',
|
|
225
|
+
value: 150,
|
|
226
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
assert.deepEqual(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-id'), {
|
|
230
|
+
randomBackoffTime: 10,
|
|
231
|
+
hashtreePrepTime: 5,
|
|
232
|
+
hashtreeResponseTime: 20,
|
|
233
|
+
syncPrepTime: 3,
|
|
234
|
+
syncResponseTime: 15,
|
|
235
|
+
syncMessageReceiveTime: 22,
|
|
236
|
+
totalTime: 50,
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('calculates sync latency values when hash tree request is skipped', () => {
|
|
241
|
+
cdl.saveTimestamp({
|
|
242
|
+
key: 'internal.client.locus.sync.start',
|
|
243
|
+
value: 100,
|
|
244
|
+
options: {
|
|
245
|
+
meetingId: 'meeting-1',
|
|
246
|
+
dataSetName: 'main',
|
|
247
|
+
randomBackoffTime: 0,
|
|
248
|
+
trackingId: 'sync-tracking-1',
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
cdl.saveTimestamp({
|
|
252
|
+
key: 'internal.client.locus.sync.request',
|
|
253
|
+
value: 110,
|
|
254
|
+
options: {
|
|
255
|
+
meetingId: 'meeting-1',
|
|
256
|
+
dataSetName: 'main',
|
|
257
|
+
trackingId: 'sync-tracking-1',
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
cdl.saveTimestamp({
|
|
261
|
+
key: 'internal.client.locus.sync.response',
|
|
262
|
+
value: 130,
|
|
263
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
264
|
+
});
|
|
265
|
+
cdl.saveTimestamp({
|
|
266
|
+
key: 'internal.client.locus.sync.message.received',
|
|
267
|
+
value: 140,
|
|
268
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
assert.deepEqual(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-1'), {
|
|
272
|
+
randomBackoffTime: 0,
|
|
273
|
+
hashtreePrepTime: 0,
|
|
274
|
+
hashtreeResponseTime: 0,
|
|
275
|
+
syncPrepTime: 10,
|
|
276
|
+
syncResponseTime: 20,
|
|
277
|
+
syncMessageReceiveTime: 30,
|
|
278
|
+
totalTime: 40,
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('associates sync response tracking id and completes the matching meeting record', () => {
|
|
283
|
+
clock.setSystemTime(150);
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
cdl.saveTimestamp({
|
|
287
|
+
key: 'internal.client.locus.sync.start',
|
|
288
|
+
value: 100,
|
|
289
|
+
options: {
|
|
290
|
+
meetingId: 'meeting-1',
|
|
291
|
+
dataSetName: 'main',
|
|
292
|
+
randomBackoffTime: 0,
|
|
293
|
+
trackingId: 'our-sync-tracking-id',
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
cdl.saveTimestamp({
|
|
297
|
+
key: 'internal.client.locus.sync.request',
|
|
298
|
+
value: 110,
|
|
299
|
+
options: {
|
|
300
|
+
meetingId: 'meeting-1',
|
|
301
|
+
dataSetName: 'main',
|
|
302
|
+
trackingId: 'our-sync-tracking-id',
|
|
303
|
+
},
|
|
304
|
+
});
|
|
305
|
+
cdl.saveTimestamp({
|
|
306
|
+
key: 'internal.client.locus.sync.response',
|
|
307
|
+
value: 130,
|
|
308
|
+
options: {
|
|
309
|
+
meetingId: 'meeting-1',
|
|
310
|
+
dataSetName: 'main',
|
|
311
|
+
trackingId: 'our-sync-tracking-id',
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
// the LLM state-update message that gates the metric arrives for this sync
|
|
315
|
+
cdl.saveTimestamp({
|
|
316
|
+
key: 'internal.client.locus.sync.message.received',
|
|
317
|
+
value: 150,
|
|
318
|
+
options: {
|
|
319
|
+
meetingId: 'meeting-1',
|
|
320
|
+
dataSetName: 'main',
|
|
321
|
+
trackingId: 'our-sync-tracking-id',
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
cdl.saveLatency('internal.client.locus.sync.random.backoff', 99, {
|
|
325
|
+
meetingId: 'meeting-1',
|
|
326
|
+
dataSetName: 'main',
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// eager completion: both the /sync response and the LLM message are present
|
|
330
|
+
assert.deepEqual(cdl.completeLocusSyncLatency('meeting-1', 'our-sync-tracking-id'), {
|
|
331
|
+
dataSet: 'main',
|
|
332
|
+
syncLatency: {
|
|
333
|
+
randomBackoffTime: 0,
|
|
334
|
+
hashtreePrepTime: 0,
|
|
335
|
+
hashtreeResponseTime: 0,
|
|
336
|
+
syncPrepTime: 10,
|
|
337
|
+
syncResponseTime: 20,
|
|
338
|
+
syncMessageReceiveTime: 40,
|
|
339
|
+
totalTime: 50,
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
// completing the metric removes the matching record, leaving only the pending
|
|
343
|
+
// backoff record created above for the next sync to consume
|
|
344
|
+
assert.lengthOf(cdl.meetingLatencies.get('meeting-1'), 1);
|
|
345
|
+
|
|
346
|
+
cdl.saveTimestamp({
|
|
347
|
+
key: 'internal.client.locus.sync.start',
|
|
348
|
+
value: 200,
|
|
349
|
+
options: {
|
|
350
|
+
meetingId: 'meeting-1',
|
|
351
|
+
dataSetName: 'main',
|
|
352
|
+
trackingId: 'next-sync-tracking-id',
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
assert.deepInclude(cdl.meetingLatencies.get('meeting-1'), {
|
|
356
|
+
locusSync: {
|
|
357
|
+
meetingId: 'meeting-1',
|
|
358
|
+
dataSetName: 'main',
|
|
359
|
+
randomBackoffTime: 99,
|
|
360
|
+
trackingId: 'next-sync-tracking-id',
|
|
361
|
+
syncStart: 200,
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
} finally {
|
|
365
|
+
clock.setSystemTime(now.getTime());
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it('does not bind message.received when tracking id does not match any record', () => {
|
|
370
|
+
clock.setSystemTime(500);
|
|
371
|
+
|
|
372
|
+
try {
|
|
373
|
+
cdl.saveTimestamp({
|
|
374
|
+
key: 'internal.client.locus.sync.start',
|
|
375
|
+
value: 100,
|
|
376
|
+
options: {
|
|
377
|
+
meetingId: 'meeting-1',
|
|
378
|
+
dataSetName: 'main',
|
|
379
|
+
randomBackoffTime: 0,
|
|
380
|
+
trackingId: 'sync-tracking-id',
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
cdl.saveTimestamp({
|
|
384
|
+
key: 'internal.client.locus.sync.request',
|
|
385
|
+
value: 110,
|
|
386
|
+
options: {
|
|
387
|
+
meetingId: 'meeting-1',
|
|
388
|
+
dataSetName: 'main',
|
|
389
|
+
trackingId: 'sync-tracking-id',
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
cdl.saveTimestamp({
|
|
393
|
+
key: 'internal.client.locus.sync.response',
|
|
394
|
+
value: 130,
|
|
395
|
+
options: {
|
|
396
|
+
meetingId: 'meeting-1',
|
|
397
|
+
dataSetName: 'main',
|
|
398
|
+
trackingId: 'sync-tracking-id',
|
|
399
|
+
},
|
|
400
|
+
});
|
|
401
|
+
cdl.saveTimestamp({
|
|
402
|
+
key: 'internal.client.locus.sync.message.received',
|
|
403
|
+
value: 140,
|
|
404
|
+
options: {
|
|
405
|
+
meetingId: 'meeting-1',
|
|
406
|
+
dataSetName: 'main',
|
|
407
|
+
trackingId: 'llm-envelope-id',
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'llm-envelope-id'));
|
|
412
|
+
assert.isUndefined(cdl.meetingLatencies.get('meeting-1')?.[0].locusSync.messageReceived);
|
|
413
|
+
} finally {
|
|
414
|
+
clock.setSystemTime(now.getTime());
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('does not allow totalTime to drop below sync response duration when message.received is stale', () => {
|
|
419
|
+
cdl.saveTimestamp({
|
|
420
|
+
key: 'internal.client.locus.sync.start',
|
|
421
|
+
value: 100,
|
|
422
|
+
options: {
|
|
423
|
+
meetingId: 'meeting-1',
|
|
424
|
+
dataSetName: 'main',
|
|
425
|
+
randomBackoffTime: 0,
|
|
426
|
+
trackingId: 'sync-tracking-id',
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
cdl.saveTimestamp({
|
|
430
|
+
key: 'internal.client.locus.sync.request',
|
|
431
|
+
value: 101,
|
|
432
|
+
options: {
|
|
433
|
+
meetingId: 'meeting-1',
|
|
434
|
+
dataSetName: 'main',
|
|
435
|
+
trackingId: 'sync-tracking-id',
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
cdl.saveTimestamp({
|
|
439
|
+
key: 'internal.client.locus.sync.response',
|
|
440
|
+
value: 475,
|
|
441
|
+
options: {
|
|
442
|
+
meetingId: 'meeting-1',
|
|
443
|
+
dataSetName: 'main',
|
|
444
|
+
trackingId: 'sync-tracking-id',
|
|
445
|
+
},
|
|
446
|
+
});
|
|
447
|
+
cdl.saveTimestamp({
|
|
448
|
+
key: 'internal.client.locus.sync.message.received',
|
|
449
|
+
value: 90,
|
|
450
|
+
options: {
|
|
451
|
+
meetingId: 'meeting-1',
|
|
452
|
+
dataSetName: 'main',
|
|
453
|
+
trackingId: 'sync-tracking-id',
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
assert.deepEqual(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'), {
|
|
458
|
+
dataSet: 'main',
|
|
459
|
+
syncLatency: {
|
|
460
|
+
randomBackoffTime: 0,
|
|
461
|
+
hashtreePrepTime: 0,
|
|
462
|
+
hashtreeResponseTime: 0,
|
|
463
|
+
syncPrepTime: 1,
|
|
464
|
+
syncResponseTime: 374,
|
|
465
|
+
syncMessageReceiveTime: 0,
|
|
466
|
+
totalTime: 375,
|
|
467
|
+
},
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it('drops and consumes a completed sync latency record when a segment exceeds the clock skew threshold', () => {
|
|
472
|
+
cdl.saveTimestamp({
|
|
473
|
+
key: 'internal.client.locus.sync.start',
|
|
474
|
+
value: 100,
|
|
475
|
+
options: {
|
|
476
|
+
meetingId: 'meeting-1',
|
|
477
|
+
dataSetName: 'main',
|
|
478
|
+
trackingId: 'sync-tracking-id',
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
cdl.saveTimestamp({
|
|
482
|
+
key: 'internal.client.locus.sync.request',
|
|
483
|
+
value: 110,
|
|
484
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
485
|
+
});
|
|
486
|
+
cdl.saveTimestamp({
|
|
487
|
+
key: 'internal.client.locus.sync.response',
|
|
488
|
+
value: 600111,
|
|
489
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
490
|
+
});
|
|
491
|
+
cdl.saveTimestamp({
|
|
492
|
+
key: 'internal.client.locus.sync.message.received',
|
|
493
|
+
value: 600112,
|
|
494
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'));
|
|
498
|
+
assert.isFalse(cdl.meetingLatencies.has('meeting-1'));
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
it('allows a completed sync latency record when the largest segment equals the clock skew threshold', () => {
|
|
502
|
+
cdl.saveTimestamp({
|
|
503
|
+
key: 'internal.client.locus.sync.start',
|
|
504
|
+
value: 100,
|
|
505
|
+
options: {
|
|
506
|
+
meetingId: 'meeting-1',
|
|
507
|
+
dataSetName: 'main',
|
|
508
|
+
trackingId: 'sync-tracking-id',
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
cdl.saveTimestamp({
|
|
512
|
+
key: 'internal.client.locus.sync.request',
|
|
513
|
+
value: 110,
|
|
514
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
515
|
+
});
|
|
516
|
+
cdl.saveTimestamp({
|
|
517
|
+
key: 'internal.client.locus.sync.response',
|
|
518
|
+
value: 600100,
|
|
519
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
520
|
+
});
|
|
521
|
+
cdl.saveTimestamp({
|
|
522
|
+
key: 'internal.client.locus.sync.message.received',
|
|
523
|
+
value: 600100,
|
|
524
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
assert.deepEqual(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'), {
|
|
528
|
+
dataSet: 'main',
|
|
529
|
+
syncLatency: {
|
|
530
|
+
randomBackoffTime: 0,
|
|
531
|
+
hashtreePrepTime: 0,
|
|
532
|
+
hashtreeResponseTime: 0,
|
|
533
|
+
syncPrepTime: 10,
|
|
534
|
+
syncResponseTime: 599990,
|
|
535
|
+
syncMessageReceiveTime: 599990,
|
|
536
|
+
totalTime: 600000,
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
assert.isFalse(cdl.meetingLatencies.has('meeting-1'));
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('matches exact record by tracking id on first pass', () => {
|
|
543
|
+
clock.setSystemTime(300);
|
|
544
|
+
|
|
545
|
+
try {
|
|
546
|
+
cdl.saveTimestamp({
|
|
547
|
+
key: 'internal.client.locus.sync.start',
|
|
548
|
+
value: 100,
|
|
549
|
+
options: {
|
|
550
|
+
meetingId: 'meeting-1',
|
|
551
|
+
dataSetName: 'main',
|
|
552
|
+
randomBackoffTime: 0,
|
|
553
|
+
trackingId: 'sync-tracking-1',
|
|
554
|
+
},
|
|
555
|
+
});
|
|
556
|
+
cdl.saveTimestamp({
|
|
557
|
+
key: 'internal.client.locus.sync.request',
|
|
558
|
+
value: 110,
|
|
559
|
+
options: {
|
|
560
|
+
meetingId: 'meeting-1',
|
|
561
|
+
dataSetName: 'main',
|
|
562
|
+
trackingId: 'sync-tracking-1',
|
|
563
|
+
},
|
|
564
|
+
});
|
|
565
|
+
cdl.saveTimestamp({
|
|
566
|
+
key: 'internal.client.locus.sync.response',
|
|
567
|
+
value: 130,
|
|
568
|
+
options: {
|
|
569
|
+
meetingId: 'meeting-1',
|
|
570
|
+
dataSetName: 'main',
|
|
571
|
+
trackingId: 'sync-tracking-1',
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
cdl.saveTimestamp({
|
|
576
|
+
key: 'internal.client.locus.sync.start',
|
|
577
|
+
value: 200,
|
|
578
|
+
options: {
|
|
579
|
+
meetingId: 'meeting-1',
|
|
580
|
+
dataSetName: 'main',
|
|
581
|
+
randomBackoffTime: 0,
|
|
582
|
+
trackingId: 'sync-tracking-2',
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
cdl.saveTimestamp({
|
|
586
|
+
key: 'internal.client.locus.sync.request',
|
|
587
|
+
value: 210,
|
|
588
|
+
options: {
|
|
589
|
+
meetingId: 'meeting-1',
|
|
590
|
+
dataSetName: 'main',
|
|
591
|
+
trackingId: 'sync-tracking-2',
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
cdl.saveTimestamp({
|
|
595
|
+
key: 'internal.client.locus.sync.response',
|
|
596
|
+
value: 230,
|
|
597
|
+
options: {
|
|
598
|
+
meetingId: 'meeting-1',
|
|
599
|
+
dataSetName: 'main',
|
|
600
|
+
trackingId: 'sync-tracking-2',
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
cdl.saveTimestamp({
|
|
604
|
+
key: 'internal.client.locus.sync.message.received',
|
|
605
|
+
value: 240,
|
|
606
|
+
options: {
|
|
607
|
+
meetingId: 'meeting-1',
|
|
608
|
+
dataSetName: 'main',
|
|
609
|
+
trackingId: 'sync-tracking-2',
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
assert.deepEqual(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-2'), {
|
|
614
|
+
dataSet: 'main',
|
|
615
|
+
syncLatency: {
|
|
616
|
+
randomBackoffTime: 0,
|
|
617
|
+
hashtreePrepTime: 0,
|
|
618
|
+
hashtreeResponseTime: 0,
|
|
619
|
+
syncPrepTime: 10,
|
|
620
|
+
syncResponseTime: 20,
|
|
621
|
+
syncMessageReceiveTime: 30,
|
|
622
|
+
totalTime: 40,
|
|
623
|
+
},
|
|
624
|
+
});
|
|
625
|
+
} finally {
|
|
626
|
+
clock.setSystemTime(now.getTime());
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
it('does not bind message.received when tracking id does not match any record', () => {
|
|
631
|
+
cdl.saveTimestamp({
|
|
632
|
+
key: 'internal.client.locus.sync.start',
|
|
633
|
+
value: 100,
|
|
634
|
+
options: {
|
|
635
|
+
meetingId: 'meeting-1',
|
|
636
|
+
dataSetName: 'main',
|
|
637
|
+
randomBackoffTime: 0,
|
|
638
|
+
trackingId: 'sync-tracking-1',
|
|
639
|
+
},
|
|
640
|
+
});
|
|
641
|
+
cdl.saveTimestamp({
|
|
642
|
+
key: 'internal.client.locus.sync.request',
|
|
643
|
+
value: 110,
|
|
644
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
645
|
+
});
|
|
646
|
+
cdl.saveTimestamp({
|
|
647
|
+
key: 'internal.client.locus.sync.response',
|
|
648
|
+
value: 130,
|
|
649
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
cdl.saveTimestamp({
|
|
653
|
+
key: 'internal.client.locus.sync.start',
|
|
654
|
+
value: 200,
|
|
655
|
+
options: {
|
|
656
|
+
meetingId: 'meeting-1',
|
|
657
|
+
dataSetName: 'main',
|
|
658
|
+
randomBackoffTime: 0,
|
|
659
|
+
trackingId: 'sync-tracking-2',
|
|
660
|
+
},
|
|
661
|
+
});
|
|
662
|
+
cdl.saveTimestamp({
|
|
663
|
+
key: 'internal.client.locus.sync.request',
|
|
664
|
+
value: 210,
|
|
665
|
+
options: {
|
|
666
|
+
meetingId: 'meeting-1',
|
|
667
|
+
dataSetName: 'main',
|
|
668
|
+
trackingId: 'sync-tracking-2',
|
|
669
|
+
},
|
|
670
|
+
});
|
|
671
|
+
cdl.saveTimestamp({
|
|
672
|
+
key: 'internal.client.locus.sync.response',
|
|
673
|
+
value: 230,
|
|
674
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
cdl.saveTimestamp({
|
|
678
|
+
key: 'internal.client.locus.sync.message.received',
|
|
679
|
+
value: 120,
|
|
680
|
+
options: {
|
|
681
|
+
meetingId: 'meeting-1',
|
|
682
|
+
dataSetName: 'main',
|
|
683
|
+
trackingId: 'llm-unknown-id',
|
|
684
|
+
},
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
688
|
+
|
|
689
|
+
assert.isDefined(records);
|
|
690
|
+
assert.lengthOf(records!, 2);
|
|
691
|
+
assert.isUndefined(records![0].locusSync.messageReceived);
|
|
692
|
+
assert.isUndefined(records![1].locusSync.messageReceived);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
it('binds message.received when the tracking id matches the only record', () => {
|
|
696
|
+
cdl.saveTimestamp({
|
|
697
|
+
key: 'internal.client.locus.sync.start',
|
|
698
|
+
value: 100,
|
|
699
|
+
options: {
|
|
700
|
+
meetingId: 'meeting-1',
|
|
701
|
+
dataSetName: 'main',
|
|
702
|
+
randomBackoffTime: 0,
|
|
703
|
+
trackingId: 'sync-tracking-id',
|
|
704
|
+
},
|
|
705
|
+
});
|
|
706
|
+
cdl.saveTimestamp({
|
|
707
|
+
key: 'internal.client.locus.sync.request',
|
|
708
|
+
value: 110,
|
|
709
|
+
options: {
|
|
710
|
+
meetingId: 'meeting-1',
|
|
711
|
+
dataSetName: 'main',
|
|
712
|
+
trackingId: 'sync-tracking-id',
|
|
713
|
+
},
|
|
714
|
+
});
|
|
715
|
+
cdl.saveTimestamp({
|
|
716
|
+
key: 'internal.client.locus.sync.response',
|
|
717
|
+
value: 130,
|
|
718
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
cdl.saveTimestamp({
|
|
722
|
+
key: 'internal.client.locus.sync.message.received',
|
|
723
|
+
value: 140,
|
|
724
|
+
options: {
|
|
725
|
+
meetingId: 'meeting-1',
|
|
726
|
+
dataSetName: 'main',
|
|
727
|
+
trackingId: 'sync-tracking-id',
|
|
728
|
+
},
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
732
|
+
|
|
733
|
+
assert.isDefined(records);
|
|
734
|
+
assert.lengthOf(records!, 1);
|
|
735
|
+
assert.equal(records![0].locusSync.messageReceived, 140);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
it('returns undefined when the tracking id does not match', () => {
|
|
739
|
+
clock.setSystemTime(150);
|
|
740
|
+
|
|
741
|
+
try {
|
|
742
|
+
cdl.saveTimestamp({
|
|
743
|
+
key: 'internal.client.locus.sync.start',
|
|
744
|
+
value: 100,
|
|
745
|
+
options: {
|
|
746
|
+
meetingId: 'meeting-1',
|
|
747
|
+
dataSetName: 'main',
|
|
748
|
+
randomBackoffTime: 0,
|
|
749
|
+
trackingId: 'our-sync-tracking-id',
|
|
750
|
+
},
|
|
751
|
+
});
|
|
752
|
+
cdl.saveTimestamp({
|
|
753
|
+
key: 'internal.client.locus.sync.request',
|
|
754
|
+
value: 110,
|
|
755
|
+
options: {
|
|
756
|
+
meetingId: 'meeting-1',
|
|
757
|
+
dataSetName: 'main',
|
|
758
|
+
trackingId: 'our-sync-tracking-id',
|
|
759
|
+
},
|
|
760
|
+
});
|
|
761
|
+
cdl.saveTimestamp({
|
|
762
|
+
key: 'internal.client.locus.sync.response',
|
|
763
|
+
value: 130,
|
|
764
|
+
options: {
|
|
765
|
+
meetingId: 'meeting-1',
|
|
766
|
+
dataSetName: 'main',
|
|
767
|
+
trackingId: 'our-sync-tracking-id',
|
|
768
|
+
},
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'llm-envelope-tracking-id'));
|
|
772
|
+
} finally {
|
|
773
|
+
clock.setSystemTime(now.getTime());
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
it('does not clean up older never-completed record for the same dataset when newer sync completes', () => {
|
|
778
|
+
// first sync: all sync milestones recorded, but its completing LLM event never arrives
|
|
779
|
+
cdl.saveTimestamp({
|
|
780
|
+
key: 'internal.client.locus.sync.start',
|
|
781
|
+
value: 100,
|
|
782
|
+
options: {
|
|
783
|
+
meetingId: 'meeting-1',
|
|
784
|
+
dataSetName: 'main',
|
|
785
|
+
randomBackoffTime: 0,
|
|
786
|
+
trackingId: 'sync-tracking-1',
|
|
787
|
+
},
|
|
788
|
+
});
|
|
789
|
+
cdl.saveTimestamp({
|
|
790
|
+
key: 'internal.client.locus.sync.request',
|
|
791
|
+
value: 110,
|
|
792
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
793
|
+
});
|
|
794
|
+
cdl.saveTimestamp({
|
|
795
|
+
key: 'internal.client.locus.sync.response',
|
|
796
|
+
value: 130,
|
|
797
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
// a second sync for the same dataset starts before the first one completed.
|
|
801
|
+
// because the first record already has syncStart set, it is not reused and a
|
|
802
|
+
// brand new record is created for the second sync
|
|
803
|
+
cdl.saveTimestamp({
|
|
804
|
+
key: 'internal.client.locus.sync.start',
|
|
805
|
+
value: 200,
|
|
806
|
+
options: {
|
|
807
|
+
meetingId: 'meeting-1',
|
|
808
|
+
dataSetName: 'main',
|
|
809
|
+
randomBackoffTime: 0,
|
|
810
|
+
trackingId: 'sync-tracking-2',
|
|
811
|
+
},
|
|
812
|
+
});
|
|
813
|
+
cdl.saveTimestamp({
|
|
814
|
+
key: 'internal.client.locus.sync.request',
|
|
815
|
+
value: 210,
|
|
816
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
817
|
+
});
|
|
818
|
+
cdl.saveTimestamp({
|
|
819
|
+
key: 'internal.client.locus.sync.response',
|
|
820
|
+
value: 230,
|
|
821
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
822
|
+
});
|
|
823
|
+
cdl.saveTimestamp({
|
|
824
|
+
key: 'internal.client.locus.sync.message.received',
|
|
825
|
+
value: 240,
|
|
826
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
// both records exist before completion
|
|
830
|
+
assert.lengthOf(cdl.meetingLatencies.get('meeting-1')!, 2);
|
|
831
|
+
|
|
832
|
+
// completing the second sync removes only its own record; the older pending record is left
|
|
833
|
+
// in place because a late LLM message could still complete it (stale cleanup is handled by
|
|
834
|
+
// the TTL / capacity pruning, not by completion).
|
|
835
|
+
const completed = cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-2');
|
|
836
|
+
|
|
837
|
+
assert.isDefined(completed);
|
|
838
|
+
assert.equal(completed!.dataSet, 'main');
|
|
839
|
+
|
|
840
|
+
const remaining = cdl.meetingLatencies.get('meeting-1');
|
|
841
|
+
|
|
842
|
+
assert.isDefined(remaining);
|
|
843
|
+
assert.lengthOf(remaining!, 1);
|
|
844
|
+
assert.equal(remaining![0].locusSync.trackingId, 'sync-tracking-1');
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
it('prunes an incomplete record once it is older than the pending TTL', () => {
|
|
848
|
+
// an incomplete sync record that never received its LLM message
|
|
849
|
+
cdl.saveTimestamp({
|
|
850
|
+
key: 'internal.client.locus.sync.start',
|
|
851
|
+
value: 100,
|
|
852
|
+
options: {
|
|
853
|
+
meetingId: 'meeting-1',
|
|
854
|
+
dataSetName: 'main',
|
|
855
|
+
trackingId: 'stale-tracking-id',
|
|
856
|
+
},
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
// a brand new sync for the same dataset starts more than the TTL later
|
|
860
|
+
cdl.saveTimestamp({
|
|
861
|
+
key: 'internal.client.locus.sync.start',
|
|
862
|
+
value: 100 + 5 * 60 * 1000 + 1,
|
|
863
|
+
options: {
|
|
864
|
+
meetingId: 'meeting-1',
|
|
865
|
+
dataSetName: 'main',
|
|
866
|
+
trackingId: 'fresh-tracking-id',
|
|
867
|
+
},
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
871
|
+
|
|
872
|
+
assert.isDefined(records);
|
|
873
|
+
assert.lengthOf(records!, 1);
|
|
874
|
+
assert.equal(records![0].locusSync.trackingId, 'fresh-tracking-id');
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
it('keeps an incomplete record that is still within the pending TTL', () => {
|
|
878
|
+
cdl.saveTimestamp({
|
|
879
|
+
key: 'internal.client.locus.sync.start',
|
|
880
|
+
value: 100,
|
|
881
|
+
options: {
|
|
882
|
+
meetingId: 'meeting-1',
|
|
883
|
+
dataSetName: 'main',
|
|
884
|
+
trackingId: 'pending-tracking-id',
|
|
885
|
+
},
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
// a new sync for the same dataset starts well within the TTL window
|
|
889
|
+
cdl.saveTimestamp({
|
|
890
|
+
key: 'internal.client.locus.sync.start',
|
|
891
|
+
value: 100 + 1000,
|
|
892
|
+
options: {
|
|
893
|
+
meetingId: 'meeting-1',
|
|
894
|
+
dataSetName: 'main',
|
|
895
|
+
trackingId: 'fresh-tracking-id',
|
|
896
|
+
},
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
900
|
+
|
|
901
|
+
assert.isDefined(records);
|
|
902
|
+
assert.lengthOf(records!, 2);
|
|
903
|
+
assert.equal(records![0].locusSync.trackingId, 'pending-tracking-id');
|
|
904
|
+
assert.equal(records![1].locusSync.trackingId, 'fresh-tracking-id');
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
it('does not prune incomplete records from a different dataset', () => {
|
|
908
|
+
cdl.saveTimestamp({
|
|
909
|
+
key: 'internal.client.locus.sync.start',
|
|
910
|
+
value: 100,
|
|
911
|
+
options: {
|
|
912
|
+
meetingId: 'meeting-1',
|
|
913
|
+
dataSetName: 'other',
|
|
914
|
+
trackingId: 'other-tracking-id',
|
|
915
|
+
},
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
// a much later sync for a different dataset must not touch the "other" record
|
|
919
|
+
cdl.saveTimestamp({
|
|
920
|
+
key: 'internal.client.locus.sync.start',
|
|
921
|
+
value: 100 + 5 * 60 * 1000 + 1,
|
|
922
|
+
options: {
|
|
923
|
+
meetingId: 'meeting-1',
|
|
924
|
+
dataSetName: 'main',
|
|
925
|
+
trackingId: 'main-tracking-id',
|
|
926
|
+
},
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
930
|
+
|
|
931
|
+
assert.isDefined(records);
|
|
932
|
+
assert.lengthOf(records!, 2);
|
|
933
|
+
assert.equal(records![0].locusSync.trackingId, 'other-tracking-id');
|
|
934
|
+
assert.equal(records![1].locusSync.trackingId, 'main-tracking-id');
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
it('caps the number of incomplete records kept per dataset', () => {
|
|
938
|
+
// create more incomplete records than the per-dataset cap, all within the TTL window
|
|
939
|
+
for (let i = 0; i <= 20; i += 1) {
|
|
940
|
+
cdl.saveTimestamp({
|
|
941
|
+
key: 'internal.client.locus.sync.start',
|
|
942
|
+
value: 100 + i,
|
|
943
|
+
options: {
|
|
944
|
+
meetingId: 'meeting-1',
|
|
945
|
+
dataSetName: 'main',
|
|
946
|
+
trackingId: `sync-tracking-${i}`,
|
|
947
|
+
},
|
|
948
|
+
});
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
952
|
+
const trackingIds = records!.map(({locusSync}) => locusSync.trackingId);
|
|
953
|
+
|
|
954
|
+
assert.isDefined(records);
|
|
955
|
+
assert.lengthOf(records!, 20);
|
|
956
|
+
// the oldest record is dropped, the newest is kept
|
|
957
|
+
assert.notInclude(trackingIds, 'sync-tracking-0');
|
|
958
|
+
assert.include(trackingIds, 'sync-tracking-20');
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
it('does not clean up never-completed records for a different dataset', () => {
|
|
962
|
+
// never-completed sync for dataset "other"
|
|
963
|
+
cdl.saveTimestamp({
|
|
964
|
+
key: 'internal.client.locus.sync.start',
|
|
965
|
+
value: 100,
|
|
966
|
+
options: {
|
|
967
|
+
meetingId: 'meeting-1',
|
|
968
|
+
dataSetName: 'other',
|
|
969
|
+
randomBackoffTime: 0,
|
|
970
|
+
trackingId: 'other-tracking-1',
|
|
971
|
+
},
|
|
972
|
+
});
|
|
973
|
+
cdl.saveTimestamp({
|
|
974
|
+
key: 'internal.client.locus.sync.request',
|
|
975
|
+
value: 110,
|
|
976
|
+
options: {meetingId: 'meeting-1', dataSetName: 'other', trackingId: 'other-tracking-1'},
|
|
977
|
+
});
|
|
978
|
+
cdl.saveTimestamp({
|
|
979
|
+
key: 'internal.client.locus.sync.response',
|
|
980
|
+
value: 130,
|
|
981
|
+
options: {meetingId: 'meeting-1', dataSetName: 'other', trackingId: 'other-tracking-1'},
|
|
982
|
+
});
|
|
983
|
+
|
|
984
|
+
// completed sync for dataset "main"
|
|
985
|
+
cdl.saveTimestamp({
|
|
986
|
+
key: 'internal.client.locus.sync.start',
|
|
987
|
+
value: 200,
|
|
988
|
+
options: {
|
|
989
|
+
meetingId: 'meeting-1',
|
|
990
|
+
dataSetName: 'main',
|
|
991
|
+
randomBackoffTime: 0,
|
|
992
|
+
trackingId: 'main-tracking-1',
|
|
993
|
+
},
|
|
994
|
+
});
|
|
995
|
+
cdl.saveTimestamp({
|
|
996
|
+
key: 'internal.client.locus.sync.request',
|
|
997
|
+
value: 210,
|
|
998
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'main-tracking-1'},
|
|
999
|
+
});
|
|
1000
|
+
cdl.saveTimestamp({
|
|
1001
|
+
key: 'internal.client.locus.sync.response',
|
|
1002
|
+
value: 230,
|
|
1003
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'main-tracking-1'},
|
|
1004
|
+
});
|
|
1005
|
+
cdl.saveTimestamp({
|
|
1006
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1007
|
+
value: 240,
|
|
1008
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'main-tracking-1'},
|
|
1009
|
+
});
|
|
1010
|
+
|
|
1011
|
+
const completed = cdl.completeLocusSyncLatency('meeting-1', 'main-tracking-1');
|
|
1012
|
+
|
|
1013
|
+
assert.isDefined(completed);
|
|
1014
|
+
|
|
1015
|
+
// the "other" dataset record must remain untouched
|
|
1016
|
+
const records = cdl.meetingLatencies.get('meeting-1');
|
|
1017
|
+
|
|
1018
|
+
assert.isDefined(records);
|
|
1019
|
+
assert.lengthOf(records!, 1);
|
|
1020
|
+
assert.equal(records![0].locusSync.dataSetName, 'other');
|
|
1021
|
+
assert.equal(records![0].locusSync.trackingId, 'other-tracking-1');
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
it('keys sync latency records by meeting id', () => {
|
|
1025
|
+
cdl.saveTimestamp({
|
|
1026
|
+
key: 'internal.client.locus.sync.start',
|
|
1027
|
+
value: 100,
|
|
1028
|
+
options: {
|
|
1029
|
+
meetingId: 'meeting-1',
|
|
1030
|
+
dataSetName: 'main',
|
|
1031
|
+
randomBackoffTime: 10,
|
|
1032
|
+
trackingId: 'sync-tracking-1',
|
|
1033
|
+
},
|
|
1034
|
+
});
|
|
1035
|
+
cdl.saveTimestamp({
|
|
1036
|
+
key: 'internal.client.locus.sync.request',
|
|
1037
|
+
value: 110,
|
|
1038
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
1039
|
+
});
|
|
1040
|
+
|
|
1041
|
+
cdl.saveTimestamp({
|
|
1042
|
+
key: 'internal.client.locus.sync.start',
|
|
1043
|
+
value: 200,
|
|
1044
|
+
options: {
|
|
1045
|
+
meetingId: 'meeting-2',
|
|
1046
|
+
dataSetName: 'main',
|
|
1047
|
+
randomBackoffTime: 23,
|
|
1048
|
+
trackingId: 'sync-tracking-2',
|
|
1049
|
+
},
|
|
1050
|
+
});
|
|
1051
|
+
cdl.saveTimestamp({
|
|
1052
|
+
key: 'internal.client.locus.sync.request',
|
|
1053
|
+
value: 217,
|
|
1054
|
+
options: {meetingId: 'meeting-2', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
1055
|
+
});
|
|
1056
|
+
cdl.saveTimestamp({
|
|
1057
|
+
key: 'internal.client.locus.sync.response',
|
|
1058
|
+
value: 241,
|
|
1059
|
+
options: {meetingId: 'meeting-2', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
1060
|
+
});
|
|
1061
|
+
cdl.saveTimestamp({
|
|
1062
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1063
|
+
value: 268,
|
|
1064
|
+
options: {meetingId: 'meeting-2', dataSetName: 'main', trackingId: 'sync-tracking-2'},
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
cdl.saveTimestamp({
|
|
1068
|
+
key: 'internal.client.locus.sync.response',
|
|
1069
|
+
value: 125,
|
|
1070
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
1071
|
+
});
|
|
1072
|
+
cdl.saveTimestamp({
|
|
1073
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1074
|
+
value: 150,
|
|
1075
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-1'},
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
assert.deepEqual(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-1'), {
|
|
1079
|
+
randomBackoffTime: 0,
|
|
1080
|
+
hashtreePrepTime: 0,
|
|
1081
|
+
hashtreeResponseTime: 0,
|
|
1082
|
+
syncPrepTime: 10,
|
|
1083
|
+
syncResponseTime: 15,
|
|
1084
|
+
syncMessageReceiveTime: 40,
|
|
1085
|
+
totalTime: 50,
|
|
1086
|
+
});
|
|
1087
|
+
assert.deepEqual(cdl.getLocusSyncLatency('meeting-2', 'sync-tracking-2'), {
|
|
1088
|
+
randomBackoffTime: 0,
|
|
1089
|
+
hashtreePrepTime: 0,
|
|
1090
|
+
hashtreeResponseTime: 0,
|
|
1091
|
+
syncPrepTime: 17,
|
|
1092
|
+
syncResponseTime: 24,
|
|
1093
|
+
syncMessageReceiveTime: 51,
|
|
1094
|
+
totalTime: 68,
|
|
1095
|
+
});
|
|
1096
|
+
|
|
1097
|
+
cdl.clearLocusSyncLatency('main', 'meeting-1');
|
|
1098
|
+
|
|
1099
|
+
assert.isUndefined(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-1'));
|
|
1100
|
+
assert.isDefined(cdl.getLocusSyncLatency('meeting-2', 'sync-tracking-2'));
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
it('returns undefined and clears state when required milestones are missing', () => {
|
|
1104
|
+
cdl.saveTimestamp({
|
|
1105
|
+
key: 'internal.client.locus.sync.start',
|
|
1106
|
+
value: 100,
|
|
1107
|
+
options: {
|
|
1108
|
+
meetingId: 'meeting-1',
|
|
1109
|
+
dataSetName: 'main',
|
|
1110
|
+
randomBackoffTime: 0,
|
|
1111
|
+
trackingId: 'sync-tracking-id',
|
|
1112
|
+
},
|
|
1113
|
+
});
|
|
1114
|
+
cdl.saveTimestamp({
|
|
1115
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1116
|
+
value: 140,
|
|
1117
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
assert.isUndefined(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-id'));
|
|
1121
|
+
cdl.clearLocusSyncLatency('main', 'meeting-1');
|
|
1122
|
+
assert.isFalse(cdl.meetingLatencies.has('meeting-1'));
|
|
1123
|
+
});
|
|
1124
|
+
|
|
1125
|
+
it('clears only the record matching the tracking id when one is supplied', () => {
|
|
1126
|
+
const stampFullRecord = (trackingId: string, base: number) => {
|
|
1127
|
+
cdl.saveTimestamp({
|
|
1128
|
+
key: 'internal.client.locus.sync.start',
|
|
1129
|
+
value: base,
|
|
1130
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1131
|
+
});
|
|
1132
|
+
cdl.saveTimestamp({
|
|
1133
|
+
key: 'internal.client.locus.sync.request',
|
|
1134
|
+
value: base + 10,
|
|
1135
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1136
|
+
});
|
|
1137
|
+
cdl.saveTimestamp({
|
|
1138
|
+
key: 'internal.client.locus.sync.response',
|
|
1139
|
+
value: base + 25,
|
|
1140
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1141
|
+
});
|
|
1142
|
+
cdl.saveTimestamp({
|
|
1143
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1144
|
+
value: base + 50,
|
|
1145
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1146
|
+
});
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
// Two records for the same dataset/meeting but different tracking ids.
|
|
1150
|
+
stampFullRecord('sync-tracking-1', 100);
|
|
1151
|
+
stampFullRecord('sync-tracking-2', 200);
|
|
1152
|
+
|
|
1153
|
+
assert.isDefined(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-1'));
|
|
1154
|
+
assert.isDefined(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-2'));
|
|
1155
|
+
|
|
1156
|
+
// Clearing with a tracking id drops only that record, leaving the other intact.
|
|
1157
|
+
cdl.clearLocusSyncLatency('main', 'meeting-1', 'sync-tracking-1');
|
|
1158
|
+
|
|
1159
|
+
assert.isUndefined(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-1'));
|
|
1160
|
+
assert.isDefined(cdl.getLocusSyncLatency('meeting-1', 'sync-tracking-2'));
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
describe('recordLocusSyncMessageReceived', () => {
|
|
1164
|
+
const startPendingSync = (trackingId: string) => {
|
|
1165
|
+
cdl.saveTimestamp({
|
|
1166
|
+
key: 'internal.client.locus.sync.start',
|
|
1167
|
+
value: 100,
|
|
1168
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1169
|
+
});
|
|
1170
|
+
};
|
|
1171
|
+
|
|
1172
|
+
it('stamps messageReceived on the matching pending record using the current time', () => {
|
|
1173
|
+
clock.setSystemTime(500);
|
|
1174
|
+
|
|
1175
|
+
try {
|
|
1176
|
+
startPendingSync('sync-tracking-id');
|
|
1177
|
+
cdl.recordLocusSyncMessageReceived('meeting-1', 'sync-tracking-id');
|
|
1178
|
+
|
|
1179
|
+
assert.equal(cdl.meetingLatencies.get('meeting-1')![0].locusSync.messageReceived, 500);
|
|
1180
|
+
} finally {
|
|
1181
|
+
clock.setSystemTime(now.getTime());
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
it('does not overwrite an already recorded messageReceived', () => {
|
|
1186
|
+
clock.setSystemTime(999);
|
|
1187
|
+
|
|
1188
|
+
try {
|
|
1189
|
+
startPendingSync('sync-tracking-id');
|
|
1190
|
+
cdl.saveTimestamp({
|
|
1191
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1192
|
+
value: 140,
|
|
1193
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId: 'sync-tracking-id'},
|
|
1194
|
+
});
|
|
1195
|
+
cdl.recordLocusSyncMessageReceived('meeting-1', 'sync-tracking-id');
|
|
1196
|
+
|
|
1197
|
+
assert.equal(cdl.meetingLatencies.get('meeting-1')![0].locusSync.messageReceived, 140);
|
|
1198
|
+
} finally {
|
|
1199
|
+
clock.setSystemTime(now.getTime());
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
it('is a no-op when no record matches the tracking id', () => {
|
|
1204
|
+
startPendingSync('sync-tracking-id');
|
|
1205
|
+
cdl.recordLocusSyncMessageReceived('meeting-1', 'some-other-tracking-id');
|
|
1206
|
+
|
|
1207
|
+
assert.isUndefined(cdl.meetingLatencies.get('meeting-1')![0].locusSync.messageReceived);
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
it('is a no-op when trackingId is empty', () => {
|
|
1211
|
+
startPendingSync('sync-tracking-id');
|
|
1212
|
+
|
|
1213
|
+
assert.doesNotThrow(() => cdl.recordLocusSyncMessageReceived('meeting-1', ''));
|
|
1214
|
+
assert.isUndefined(cdl.meetingLatencies.get('meeting-1')![0].locusSync.messageReceived);
|
|
1215
|
+
});
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
describe('completeLocusSyncLatency requires both milestones', () => {
|
|
1219
|
+
const recordSyncRequest = (trackingId: string) => {
|
|
1220
|
+
cdl.saveTimestamp({
|
|
1221
|
+
key: 'internal.client.locus.sync.start',
|
|
1222
|
+
value: 100,
|
|
1223
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1224
|
+
});
|
|
1225
|
+
cdl.saveTimestamp({
|
|
1226
|
+
key: 'internal.client.locus.sync.request',
|
|
1227
|
+
value: 110,
|
|
1228
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1229
|
+
});
|
|
1230
|
+
};
|
|
1231
|
+
const recordSyncResponse = (trackingId: string) =>
|
|
1232
|
+
cdl.saveTimestamp({
|
|
1233
|
+
key: 'internal.client.locus.sync.response',
|
|
1234
|
+
value: 130,
|
|
1235
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1236
|
+
});
|
|
1237
|
+
const recordMessageReceived = (trackingId: string) =>
|
|
1238
|
+
cdl.saveTimestamp({
|
|
1239
|
+
key: 'internal.client.locus.sync.message.received',
|
|
1240
|
+
value: 150,
|
|
1241
|
+
options: {meetingId: 'meeting-1', dataSetName: 'main', trackingId},
|
|
1242
|
+
});
|
|
1243
|
+
|
|
1244
|
+
it('returns undefined and keeps the record when only the /sync response is present', () => {
|
|
1245
|
+
recordSyncRequest('sync-tracking-id');
|
|
1246
|
+
recordSyncResponse('sync-tracking-id');
|
|
1247
|
+
|
|
1248
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'));
|
|
1249
|
+
assert.lengthOf(cdl.meetingLatencies.get('meeting-1')!, 1);
|
|
1250
|
+
});
|
|
1251
|
+
|
|
1252
|
+
it('returns undefined and keeps the record when only the LLM message is present', () => {
|
|
1253
|
+
recordSyncRequest('sync-tracking-id');
|
|
1254
|
+
recordMessageReceived('sync-tracking-id');
|
|
1255
|
+
|
|
1256
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'));
|
|
1257
|
+
assert.lengthOf(cdl.meetingLatencies.get('meeting-1')!, 1);
|
|
1258
|
+
});
|
|
1259
|
+
|
|
1260
|
+
it('emits and consumes the record when the /sync response arrives after the LLM message', () => {
|
|
1261
|
+
recordSyncRequest('sync-tracking-id');
|
|
1262
|
+
// LLM message arrives first, before the HTTP response
|
|
1263
|
+
recordMessageReceived('sync-tracking-id');
|
|
1264
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'));
|
|
1265
|
+
|
|
1266
|
+
// /sync response lands second -> now both milestones are in
|
|
1267
|
+
recordSyncResponse('sync-tracking-id');
|
|
1268
|
+
|
|
1269
|
+
assert.deepEqual(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'), {
|
|
1270
|
+
dataSet: 'main',
|
|
1271
|
+
syncLatency: {
|
|
1272
|
+
randomBackoffTime: 0,
|
|
1273
|
+
hashtreePrepTime: 0,
|
|
1274
|
+
hashtreeResponseTime: 0,
|
|
1275
|
+
syncPrepTime: 10,
|
|
1276
|
+
syncResponseTime: 20,
|
|
1277
|
+
syncMessageReceiveTime: 40,
|
|
1278
|
+
totalTime: 50,
|
|
1279
|
+
},
|
|
1280
|
+
});
|
|
1281
|
+
assert.isUndefined(cdl.meetingLatencies.get('meeting-1'));
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1284
|
+
it('emits and consumes the record when the LLM message arrives after the /sync response', () => {
|
|
1285
|
+
recordSyncRequest('sync-tracking-id');
|
|
1286
|
+
// HTTP response arrives first
|
|
1287
|
+
recordSyncResponse('sync-tracking-id');
|
|
1288
|
+
assert.isUndefined(cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id'));
|
|
1289
|
+
|
|
1290
|
+
// LLM message lands second
|
|
1291
|
+
recordMessageReceived('sync-tracking-id');
|
|
1292
|
+
|
|
1293
|
+
const completed = cdl.completeLocusSyncLatency('meeting-1', 'sync-tracking-id');
|
|
1294
|
+
|
|
1295
|
+
assert.isDefined(completed);
|
|
1296
|
+
assert.equal(completed!.dataSet, 'main');
|
|
1297
|
+
assert.isUndefined(cdl.meetingLatencies.get('meeting-1'));
|
|
1298
|
+
});
|
|
1299
|
+
});
|
|
116
1300
|
});
|
|
117
1301
|
|
|
118
1302
|
it('should calculate diff between timestamps correctly', () => {
|
|
@@ -235,20 +1419,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
235
1419
|
});
|
|
236
1420
|
|
|
237
1421
|
describe('measureLatency', () => {
|
|
238
|
-
let clock;
|
|
239
1422
|
let saveLatencySpy;
|
|
240
1423
|
|
|
241
1424
|
beforeEach(() => {
|
|
242
|
-
clock = sinon.useFakeTimers();
|
|
243
|
-
|
|
244
1425
|
saveLatencySpy = sinon.stub(cdl, 'saveLatency');
|
|
245
1426
|
});
|
|
246
1427
|
|
|
247
|
-
afterEach(() => {
|
|
248
|
-
clock.restore();
|
|
249
|
-
sinon.restore();
|
|
250
|
-
});
|
|
251
|
-
|
|
252
1428
|
it('checks measureLatency with accumulate false', async () => {
|
|
253
1429
|
const key = 'internal.client.pageJMT';
|
|
254
1430
|
const accumulate = false;
|
|
@@ -264,7 +1440,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
264
1440
|
const resolvedValue = await promise;
|
|
265
1441
|
assert.deepEqual(resolvedValue, 'test');
|
|
266
1442
|
assert.calledOnceWithExactly(callbackStub);
|
|
267
|
-
assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
|
|
1443
|
+
assert.calledOnceWithExactly(saveLatencySpy, key, 50, {accumulate});
|
|
268
1444
|
});
|
|
269
1445
|
|
|
270
1446
|
it('checks measureLatency with accumulate true', async () => {
|
|
@@ -280,7 +1456,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
280
1456
|
const resolvedValue = await promise;
|
|
281
1457
|
assert.deepEqual(resolvedValue, 'test123');
|
|
282
1458
|
assert.calledOnceWithExactly(callbackStub);
|
|
283
|
-
assert.calledOnceWithExactly(saveLatencySpy, key, 20, accumulate);
|
|
1459
|
+
assert.calledOnceWithExactly(saveLatencySpy, key, 20, {accumulate});
|
|
284
1460
|
});
|
|
285
1461
|
|
|
286
1462
|
it('checks measureLatency when callBack rejects', async () => {
|
|
@@ -297,7 +1473,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
297
1473
|
const rejectedValue = await assert.isRejected(promise);
|
|
298
1474
|
assert.deepEqual(rejectedValue, error);
|
|
299
1475
|
assert.calledOnceWithExactly(callbackStub);
|
|
300
|
-
assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
|
|
1476
|
+
assert.calledOnceWithExactly(saveLatencySpy, key, 50, {accumulate});
|
|
301
1477
|
});
|
|
302
1478
|
});
|
|
303
1479
|
|
|
@@ -412,8 +1588,10 @@ describe('internal-plugin-metrics', () => {
|
|
|
412
1588
|
});
|
|
413
1589
|
|
|
414
1590
|
it('calculates getCallInitJoinReq correctly', () => {
|
|
1591
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 5});
|
|
415
1592
|
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
416
1593
|
cdl.saveTimestamp({key: 'client.locus.join.request', value: 20});
|
|
1594
|
+
// showedToJoinReq = 20-5 = 15, showInterstitialTime = 10-5 = 5, result = 15-5 = 10
|
|
417
1595
|
assert.deepEqual(cdl.getCallInitJoinReq(), 10);
|
|
418
1596
|
});
|
|
419
1597
|
|
|
@@ -509,7 +1687,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
509
1687
|
|
|
510
1688
|
it('calculates getStayLobbyTime correctly', () => {
|
|
511
1689
|
cdl.saveTimestamp({
|
|
512
|
-
key: 'client.
|
|
1690
|
+
key: 'client.lobby.entered',
|
|
513
1691
|
value: 10,
|
|
514
1692
|
});
|
|
515
1693
|
cdl.saveTimestamp({
|
|
@@ -519,6 +1697,50 @@ describe('internal-plugin-metrics', () => {
|
|
|
519
1697
|
assert.deepEqual(cdl.getStayLobbyTime(), 10);
|
|
520
1698
|
});
|
|
521
1699
|
|
|
1700
|
+
describe('getStayLobbyTimeCappedBy', () => {
|
|
1701
|
+
it('returns 0 when lobbyStartTimestamp is missing', () => {
|
|
1702
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 100});
|
|
1703
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 0);
|
|
1704
|
+
});
|
|
1705
|
+
|
|
1706
|
+
it('returns undefined when endTimestampKey is missing', () => {
|
|
1707
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 10});
|
|
1708
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), undefined);
|
|
1709
|
+
});
|
|
1710
|
+
|
|
1711
|
+
it('uses maximumEndTimestamp when lobby end does not exist', () => {
|
|
1712
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 10});
|
|
1713
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
1714
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 40);
|
|
1715
|
+
});
|
|
1716
|
+
|
|
1717
|
+
it('uses lobby end when it is before maximumEndTimestamp', () => {
|
|
1718
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 10});
|
|
1719
|
+
cdl.saveTimestamp({key: 'client.lobby.exited', value: 30});
|
|
1720
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
1721
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 20);
|
|
1722
|
+
});
|
|
1723
|
+
|
|
1724
|
+
it('uses maximumEndTimestamp when lobby end is after it', () => {
|
|
1725
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 10});
|
|
1726
|
+
cdl.saveTimestamp({key: 'client.lobby.exited', value: 60});
|
|
1727
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
1728
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 40);
|
|
1729
|
+
});
|
|
1730
|
+
|
|
1731
|
+
it('clamps to 0 when result would be negative', () => {
|
|
1732
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 100});
|
|
1733
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
1734
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 0);
|
|
1735
|
+
});
|
|
1736
|
+
|
|
1737
|
+
it('clamps to MAX_INTEGER when result is very large', () => {
|
|
1738
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 0});
|
|
1739
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 2147483648});
|
|
1740
|
+
assert.deepEqual(cdl.getStayLobbyTimeCappedBy('client.media-engine.ready'), 2147483647);
|
|
1741
|
+
});
|
|
1742
|
+
});
|
|
1743
|
+
|
|
522
1744
|
it('calculates getPageJMT correctly', () => {
|
|
523
1745
|
cdl.saveLatency('internal.client.pageJMT', 10);
|
|
524
1746
|
assert.deepEqual(cdl.getPageJMT(), 10);
|
|
@@ -530,76 +1752,40 @@ describe('internal-plugin-metrics', () => {
|
|
|
530
1752
|
});
|
|
531
1753
|
|
|
532
1754
|
it('calculates getClickToInterstitial correctly', () => {
|
|
533
|
-
cdl.saveTimestamp({
|
|
534
|
-
key: 'internal.client.meeting.click.joinbutton',
|
|
535
|
-
value: 10,
|
|
536
|
-
});
|
|
537
|
-
cdl.saveTimestamp({
|
|
538
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
539
|
-
value: 20,
|
|
540
|
-
});
|
|
541
|
-
assert.deepEqual(cdl.getClickToInterstitial(), 10);
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
it('calculates getClickToInterstitial without join button timestamp', () => {
|
|
545
1755
|
cdl.saveLatency('internal.click.to.interstitial', 5);
|
|
546
|
-
cdl.saveTimestamp({
|
|
547
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
548
|
-
value: 20,
|
|
549
|
-
});
|
|
550
1756
|
assert.deepEqual(cdl.getClickToInterstitial(), 5);
|
|
551
1757
|
});
|
|
552
1758
|
|
|
553
|
-
it('calculates getClickToInterstitial
|
|
1759
|
+
it('calculates getClickToInterstitial correctly when it is 0', () => {
|
|
554
1760
|
cdl.saveLatency('internal.click.to.interstitial', 0);
|
|
555
|
-
cdl.saveTimestamp({
|
|
556
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
557
|
-
value: 20,
|
|
558
|
-
});
|
|
559
1761
|
assert.deepEqual(cdl.getClickToInterstitial(), 0);
|
|
560
1762
|
});
|
|
561
1763
|
|
|
562
|
-
it('calculates getClickToInterstitial
|
|
1764
|
+
it('calculates getClickToInterstitial correctly when it is greater than MAX_INTEGER', () => {
|
|
563
1765
|
cdl.saveLatency('internal.click.to.interstitial', 2147483648);
|
|
564
1766
|
assert.deepEqual(cdl.getClickToInterstitial(), 2147483647);
|
|
565
1767
|
});
|
|
566
1768
|
|
|
567
1769
|
it('calculates getClickToInterstitialWithUserDelay correctly', () => {
|
|
568
|
-
cdl.saveTimestamp({
|
|
569
|
-
key: 'internal.client.meeting.click.joinbutton',
|
|
570
|
-
value: 10,
|
|
571
|
-
});
|
|
572
|
-
cdl.saveTimestamp({
|
|
573
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
574
|
-
value: 20,
|
|
575
|
-
});
|
|
576
|
-
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 10);
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
it('calculates getClickToInterstitialWithUserDelay without join button timestamp', () => {
|
|
580
1770
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 5);
|
|
581
|
-
cdl.saveTimestamp({
|
|
582
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
583
|
-
value: 20,
|
|
584
|
-
});
|
|
585
1771
|
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 5);
|
|
586
1772
|
});
|
|
587
1773
|
|
|
588
|
-
it('calculates getClickToInterstitialWithUserDelay
|
|
1774
|
+
it('calculates getClickToInterstitialWithUserDelay correctly when it is 0', () => {
|
|
589
1775
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
|
|
590
|
-
cdl.saveTimestamp({
|
|
591
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
592
|
-
value: 20,
|
|
593
|
-
});
|
|
594
1776
|
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 0);
|
|
595
1777
|
});
|
|
596
1778
|
|
|
597
|
-
it('calculates getClickToInterstitialWithUserDelay
|
|
1779
|
+
it('calculates getClickToInterstitialWithUserDelay correctly when it is greater than MAX_INTEGER', () => {
|
|
598
1780
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
|
|
599
1781
|
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 2147483647);
|
|
600
1782
|
});
|
|
601
1783
|
|
|
602
1784
|
it('calculates getInterstitialToJoinOK correctly', () => {
|
|
1785
|
+
cdl.saveTimestamp({
|
|
1786
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
1787
|
+
value: 5,
|
|
1788
|
+
});
|
|
603
1789
|
cdl.saveTimestamp({
|
|
604
1790
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
605
1791
|
value: 10,
|
|
@@ -608,12 +1794,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
608
1794
|
key: 'client.locus.join.response',
|
|
609
1795
|
value: 20,
|
|
610
1796
|
});
|
|
1797
|
+
// showedToJoinResp = 20-5 = 15, showInterstitialTime = 10-5 = 5, result = 15-5 = 10
|
|
611
1798
|
assert.deepEqual(cdl.getInterstitialToJoinOK(), 10);
|
|
612
1799
|
});
|
|
613
1800
|
|
|
614
1801
|
it('calculates getInterstitialToJoinOK correctly when one value is not a number', () => {
|
|
615
1802
|
cdl.saveTimestamp({
|
|
616
|
-
key: 'internal.client.interstitial-window.
|
|
1803
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
617
1804
|
value: 'ten' as unknown as number,
|
|
618
1805
|
});
|
|
619
1806
|
cdl.saveTimestamp({
|
|
@@ -624,22 +1811,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
624
1811
|
});
|
|
625
1812
|
|
|
626
1813
|
it('calculates getCallInitMediaEngineReady correctly', () => {
|
|
627
|
-
cdl.
|
|
628
|
-
|
|
629
|
-
value: 10,
|
|
630
|
-
});
|
|
631
|
-
cdl.saveTimestamp({
|
|
632
|
-
key: 'client.media-engine.ready',
|
|
633
|
-
value: 20,
|
|
634
|
-
});
|
|
635
|
-
assert.deepEqual(cdl.getCallInitMediaEngineReady(), 10);
|
|
1814
|
+
sinon.stub(cdl, 'getInterstitialToMediaOKJMT').returns(42);
|
|
1815
|
+
assert.deepEqual(cdl.getCallInitMediaEngineReady(), 42);
|
|
636
1816
|
});
|
|
637
1817
|
|
|
638
1818
|
it('calculates getTotalJMT correctly', () => {
|
|
639
|
-
cdl.
|
|
640
|
-
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
641
|
-
value: 5,
|
|
642
|
-
});
|
|
1819
|
+
cdl.saveLatency('internal.click.to.interstitial', 10);
|
|
643
1820
|
cdl.saveTimestamp({
|
|
644
1821
|
key: 'internal.client.meeting.click.joinbutton',
|
|
645
1822
|
value: 10,
|
|
@@ -648,29 +1825,39 @@ describe('internal-plugin-metrics', () => {
|
|
|
648
1825
|
key: 'internal.client.meeting.interstitial-window.showed',
|
|
649
1826
|
value: 20,
|
|
650
1827
|
});
|
|
1828
|
+
cdl.saveTimestamp({
|
|
1829
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
1830
|
+
value: 25,
|
|
1831
|
+
});
|
|
651
1832
|
cdl.saveTimestamp({
|
|
652
1833
|
key: 'client.locus.join.response',
|
|
653
1834
|
value: 40,
|
|
654
1835
|
});
|
|
655
|
-
|
|
1836
|
+
// clickToInterstitial = 20-10 = 10
|
|
1837
|
+
// showedToJoinLocusResponse = 40-20 = 20
|
|
1838
|
+
// showInterstitialTime = 25-20 = 5
|
|
1839
|
+
// total = 10 + 20 - 5 = 25
|
|
1840
|
+
assert.deepEqual(cdl.getTotalJMT(), 25);
|
|
656
1841
|
});
|
|
657
1842
|
|
|
658
1843
|
it('calculates getTotalJMT correctly when clickToInterstitial is 0', () => {
|
|
659
1844
|
cdl.saveLatency('internal.click.to.interstitial', 0);
|
|
660
1845
|
cdl.saveTimestamp({
|
|
661
|
-
key: 'internal.client.interstitial-window.
|
|
1846
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
662
1847
|
value: 20,
|
|
663
1848
|
});
|
|
664
1849
|
cdl.saveTimestamp({
|
|
665
1850
|
key: 'client.locus.join.response',
|
|
666
1851
|
value: 40,
|
|
667
1852
|
});
|
|
1853
|
+
// showedToJoinLocusResponse = 40-20 = 20, showInterstitialTime = 0
|
|
1854
|
+
// total = 0 + 20 - 0 = 20
|
|
668
1855
|
assert.deepEqual(cdl.getTotalJMT(), 20);
|
|
669
1856
|
});
|
|
670
1857
|
|
|
671
|
-
it('calculates getTotalJMT correctly when
|
|
1858
|
+
it('calculates getTotalJMT correctly when interstitialClickJoinToJoinLocusResponse is 0', () => {
|
|
672
1859
|
cdl.saveTimestamp({
|
|
673
|
-
key: 'internal.client.interstitial-window.
|
|
1860
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
674
1861
|
value: 40,
|
|
675
1862
|
});
|
|
676
1863
|
cdl.saveLatency('internal.click.to.interstitial', 12);
|
|
@@ -678,12 +1865,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
678
1865
|
key: 'client.locus.join.response',
|
|
679
1866
|
value: 40,
|
|
680
1867
|
});
|
|
1868
|
+
// showedToJoinLocusResponse = 0, showInterstitialTime = 0
|
|
1869
|
+
// total = 12 + 0 - 0 = 12
|
|
681
1870
|
assert.deepEqual(cdl.getTotalJMT(), 12);
|
|
682
1871
|
});
|
|
683
1872
|
|
|
684
|
-
it('calculates getTotalJMT correctly when both clickToInterstitial and
|
|
1873
|
+
it('calculates getTotalJMT correctly when both clickToInterstitial and interstitialClickJoinToJoinLocusResponse are 0', () => {
|
|
685
1874
|
cdl.saveTimestamp({
|
|
686
|
-
key: 'internal.client.interstitial-window.
|
|
1875
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
687
1876
|
value: 40,
|
|
688
1877
|
});
|
|
689
1878
|
cdl.saveLatency('internal.click.to.interstitial', 0);
|
|
@@ -696,7 +1885,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
696
1885
|
|
|
697
1886
|
it('calculates getTotalJMT correctly when both clickToInterstitial is not a number', () => {
|
|
698
1887
|
cdl.saveTimestamp({
|
|
699
|
-
key: 'internal.client.interstitial-window.
|
|
1888
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
700
1889
|
value: 40,
|
|
701
1890
|
});
|
|
702
1891
|
cdl.saveLatency('internal.click.to.interstitial', 'eleven' as unknown as number);
|
|
@@ -709,7 +1898,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
709
1898
|
|
|
710
1899
|
it('calculates getTotalJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
711
1900
|
cdl.saveTimestamp({
|
|
712
|
-
key: 'internal.client.interstitial-window.
|
|
1901
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
713
1902
|
value: 5,
|
|
714
1903
|
});
|
|
715
1904
|
cdl.saveTimestamp({
|
|
@@ -721,14 +1910,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
721
1910
|
});
|
|
722
1911
|
|
|
723
1912
|
it('calculates getTotalJMTWithUserDelay correctly', () => {
|
|
724
|
-
cdl.
|
|
725
|
-
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
726
|
-
value: 5,
|
|
727
|
-
});
|
|
728
|
-
cdl.saveTimestamp({
|
|
729
|
-
key: 'internal.client.meeting.click.joinbutton',
|
|
730
|
-
value: 10,
|
|
731
|
-
});
|
|
1913
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 10);
|
|
732
1914
|
cdl.saveTimestamp({
|
|
733
1915
|
key: 'internal.client.meeting.interstitial-window.showed',
|
|
734
1916
|
value: 20,
|
|
@@ -737,13 +1919,13 @@ describe('internal-plugin-metrics', () => {
|
|
|
737
1919
|
key: 'client.locus.join.response',
|
|
738
1920
|
value: 40,
|
|
739
1921
|
});
|
|
740
|
-
assert.deepEqual(cdl.getTotalJMTWithUserDelay(),
|
|
1922
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 30);
|
|
741
1923
|
});
|
|
742
1924
|
|
|
743
1925
|
it('calculates getTotalJMTWithUserDelay correctly when clickToInterstitialWithUserDelay is 0', () => {
|
|
744
1926
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
|
|
745
1927
|
cdl.saveTimestamp({
|
|
746
|
-
key: 'internal.client.interstitial-window.
|
|
1928
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
747
1929
|
value: 20,
|
|
748
1930
|
});
|
|
749
1931
|
cdl.saveTimestamp({
|
|
@@ -753,9 +1935,9 @@ describe('internal-plugin-metrics', () => {
|
|
|
753
1935
|
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 20);
|
|
754
1936
|
});
|
|
755
1937
|
|
|
756
|
-
it('calculates getTotalJMTWithUserDelay correctly when
|
|
1938
|
+
it('calculates getTotalJMTWithUserDelay correctly when interstitialShowedToJoinLocusResponse is 0', () => {
|
|
757
1939
|
cdl.saveTimestamp({
|
|
758
|
-
key: 'internal.client.interstitial-window.
|
|
1940
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
759
1941
|
value: 40,
|
|
760
1942
|
});
|
|
761
1943
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 12);
|
|
@@ -766,9 +1948,9 @@ describe('internal-plugin-metrics', () => {
|
|
|
766
1948
|
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 12);
|
|
767
1949
|
});
|
|
768
1950
|
|
|
769
|
-
it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay and
|
|
1951
|
+
it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay and interstitialShowedToJoinLocusResponse are 0', () => {
|
|
770
1952
|
cdl.saveTimestamp({
|
|
771
|
-
key: 'internal.client.interstitial-window.
|
|
1953
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
772
1954
|
value: 40,
|
|
773
1955
|
});
|
|
774
1956
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
|
|
@@ -781,7 +1963,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
781
1963
|
|
|
782
1964
|
it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay is not a number', () => {
|
|
783
1965
|
cdl.saveTimestamp({
|
|
784
|
-
key: 'internal.client.interstitial-window.
|
|
1966
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
785
1967
|
value: 40,
|
|
786
1968
|
});
|
|
787
1969
|
cdl.saveLatency(
|
|
@@ -798,7 +1980,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
798
1980
|
it('calculates getTotalJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => {
|
|
799
1981
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
|
|
800
1982
|
cdl.saveTimestamp({
|
|
801
|
-
key: 'internal.client.interstitial-window.
|
|
1983
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
802
1984
|
value: 20,
|
|
803
1985
|
});
|
|
804
1986
|
cdl.saveTimestamp({
|
|
@@ -808,215 +1990,111 @@ describe('internal-plugin-metrics', () => {
|
|
|
808
1990
|
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 2147483647);
|
|
809
1991
|
});
|
|
810
1992
|
|
|
811
|
-
it('calculates getTotalMediaJMT correctly', () => {
|
|
812
|
-
cdl.
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
});
|
|
816
|
-
cdl.saveTimestamp({
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
});
|
|
820
|
-
cdl.saveTimestamp({
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
});
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
cdl.
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
cdl.
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
});
|
|
844
|
-
|
|
1993
|
+
it('calculates getTotalMediaJMT correctly with lobby exiting before media-engine.ready', () => {
|
|
1994
|
+
cdl.saveLatency('internal.click.to.interstitial', 3);
|
|
1995
|
+
// clickToInterstitial = 3
|
|
1996
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
|
|
1997
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
1998
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
1999
|
+
// interstitialShowedToMediaEngineReady = 50 - 8 = 42
|
|
2000
|
+
// showInterstitialTime = 10 - 8 = 2
|
|
2001
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 20});
|
|
2002
|
+
cdl.saveTimestamp({key: 'client.lobby.exited', value: 30});
|
|
2003
|
+
// stayLobbyTimeCappedByMediaEngineReady = min(30, 50) - 20 = 10
|
|
2004
|
+
// total = 3 + 42 - 2 - 10 = 33
|
|
2005
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 33);
|
|
2006
|
+
});
|
|
2007
|
+
|
|
2008
|
+
it('calculates getTotalMediaJMT correctly without lobby', () => {
|
|
2009
|
+
cdl.saveLatency('internal.click.to.interstitial', 3);
|
|
2010
|
+
// clickToInterstitial = 3
|
|
2011
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
|
|
2012
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
2013
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
2014
|
+
// interstitialShowedToMediaEngineReady = 50 - 8 = 42
|
|
2015
|
+
// showInterstitialTime = 10 - 8 = 2
|
|
2016
|
+
// no client.lobby.entered → stayLobbyTimeCappedByMediaEngineReady = 0
|
|
2017
|
+
// total = 3 + 42 - 2 - 0 = 43
|
|
2018
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 43);
|
|
2019
|
+
});
|
|
2020
|
+
|
|
2021
|
+
it('calculates getTotalMediaJMT correctly with lobby exiting after media-engine.ready', () => {
|
|
2022
|
+
cdl.saveLatency('internal.click.to.interstitial', 3);
|
|
2023
|
+
// clickToInterstitial = 3
|
|
2024
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
|
|
2025
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
2026
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
2027
|
+
// interstitialShowedToMediaEngineReady = 50 - 8 = 42
|
|
2028
|
+
// showInterstitialTime = 10 - 8 = 2
|
|
2029
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 20});
|
|
2030
|
+
cdl.saveTimestamp({key: 'client.lobby.exited', value: 60});
|
|
2031
|
+
// stayLobbyTimeCappedByMediaEngineReady = min(60, 50) - 20 = 30
|
|
2032
|
+
// total = 3 + 42 - 2 - 30 = 13
|
|
2033
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 13);
|
|
845
2034
|
});
|
|
846
2035
|
|
|
847
2036
|
it('calculates getTotalMediaJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
848
|
-
cdl.
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
});
|
|
852
|
-
cdl.saveTimestamp({
|
|
853
|
-
|
|
854
|
-
value: 8,
|
|
855
|
-
});
|
|
856
|
-
cdl.saveTimestamp({
|
|
857
|
-
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
858
|
-
value: 10,
|
|
859
|
-
});
|
|
860
|
-
cdl.saveTimestamp({
|
|
861
|
-
key: 'client.locus.join.request',
|
|
862
|
-
value: 12,
|
|
863
|
-
});
|
|
864
|
-
cdl.saveTimestamp({
|
|
865
|
-
key: 'client.locus.join.response',
|
|
866
|
-
value: 2147483700,
|
|
867
|
-
});
|
|
868
|
-
cdl.saveTimestamp({
|
|
869
|
-
key: 'client.lobby.exited',
|
|
870
|
-
value: 2147483800,
|
|
871
|
-
});
|
|
872
|
-
cdl.saveTimestamp({
|
|
873
|
-
key: 'client.ice.start',
|
|
874
|
-
value: 30,
|
|
875
|
-
});
|
|
876
|
-
cdl.saveTimestamp({
|
|
877
|
-
key: 'client.ice.end',
|
|
878
|
-
value: 100,
|
|
879
|
-
});
|
|
2037
|
+
cdl.saveLatency('internal.click.to.interstitial', 5);
|
|
2038
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
|
|
2039
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
2040
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 4294967400});
|
|
2041
|
+
cdl.saveTimestamp({key: 'client.lobby.entered', value: 28});
|
|
2042
|
+
cdl.saveTimestamp({key: 'client.lobby.exited', value: 30});
|
|
880
2043
|
assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
|
|
881
2044
|
});
|
|
882
2045
|
|
|
883
|
-
it('
|
|
884
|
-
cdl.
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
cdl.saveTimestamp({
|
|
890
|
-
key: 'internal.client.meeting.interstitial-window.showed',
|
|
891
|
-
value: 8,
|
|
892
|
-
});
|
|
893
|
-
cdl.saveTimestamp({
|
|
894
|
-
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
895
|
-
value: 10,
|
|
896
|
-
});
|
|
897
|
-
cdl.saveTimestamp({
|
|
898
|
-
key: 'client.locus.join.request',
|
|
899
|
-
value: 12,
|
|
900
|
-
});
|
|
901
|
-
cdl.saveTimestamp({
|
|
902
|
-
key: 'client.locus.join.response',
|
|
903
|
-
value: 20,
|
|
904
|
-
});
|
|
905
|
-
cdl.saveTimestamp({
|
|
906
|
-
key: 'client.lobby.exited',
|
|
907
|
-
value: 24,
|
|
908
|
-
});
|
|
909
|
-
cdl.saveTimestamp({
|
|
910
|
-
key: 'client.ice.start',
|
|
911
|
-
value: 30,
|
|
912
|
-
});
|
|
913
|
-
cdl.saveTimestamp({
|
|
914
|
-
key: 'client.ice.end',
|
|
915
|
-
value: 40,
|
|
916
|
-
});
|
|
917
|
-
assert.deepEqual(cdl.getTotalMediaJMT(), 31);
|
|
2046
|
+
it('returns undefined for getTotalMediaJMT when media-engine.ready is missing', () => {
|
|
2047
|
+
cdl.saveLatency('internal.click.to.interstitial', 3);
|
|
2048
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
|
|
2049
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
2050
|
+
cdl.saveTimestamp({key: 'client.locus.join.response', value: 20});
|
|
2051
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), undefined);
|
|
918
2052
|
});
|
|
919
2053
|
|
|
920
|
-
it('calculates getTotalMediaJMT correctly
|
|
921
|
-
cdl.
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
});
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
cdl.
|
|
931
|
-
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
932
|
-
value: 1000,
|
|
933
|
-
});
|
|
934
|
-
cdl.saveTimestamp({
|
|
935
|
-
key: 'client.locus.join.request',
|
|
936
|
-
value: 2000,
|
|
937
|
-
});
|
|
938
|
-
cdl.saveTimestamp({
|
|
939
|
-
key: 'client.locus.join.response',
|
|
940
|
-
value: 2147483700,
|
|
941
|
-
});
|
|
942
|
-
cdl.saveTimestamp({
|
|
943
|
-
key: 'client.lobby.exited',
|
|
944
|
-
value: 2147483800,
|
|
945
|
-
});
|
|
946
|
-
cdl.saveTimestamp({
|
|
947
|
-
key: 'client.ice.start',
|
|
948
|
-
value: 2147483900,
|
|
949
|
-
});
|
|
950
|
-
cdl.saveTimestamp({
|
|
951
|
-
key: 'client.ice.end',
|
|
952
|
-
value: 4294967400,
|
|
953
|
-
});
|
|
954
|
-
assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
|
|
2054
|
+
it('calculates getTotalMediaJMT correctly when there is no lobby and stayLobbyTime defaults to 0', () => {
|
|
2055
|
+
cdl.saveLatency('internal.click.to.interstitial', 3);
|
|
2056
|
+
// clickToInterstitial = 3
|
|
2057
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
|
|
2058
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 10});
|
|
2059
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
2060
|
+
// interstitialShowedToMediaEngineReady = 50 - 8 = 42
|
|
2061
|
+
// showInterstitialTime = 10 - 8 = 2
|
|
2062
|
+
// no client.lobby.entered → stayLobbyTimeCappedByMediaEngineReady = 0
|
|
2063
|
+
// total = 3 + 42 - 2 - 0 = 43
|
|
2064
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 43);
|
|
955
2065
|
});
|
|
956
2066
|
|
|
957
2067
|
it('calculates getTotalMediaJMTWithUserDelay correctly', () => {
|
|
958
2068
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
value: 12,
|
|
966
|
-
});
|
|
967
|
-
cdl.saveTimestamp({
|
|
968
|
-
key: 'client.locus.join.response',
|
|
969
|
-
value: 20,
|
|
970
|
-
});
|
|
971
|
-
cdl.saveTimestamp({
|
|
972
|
-
key: 'internal.host.meeting.participant.admitted',
|
|
973
|
-
value: 24,
|
|
974
|
-
});
|
|
975
|
-
cdl.saveTimestamp({
|
|
976
|
-
key: 'client.ice.start',
|
|
977
|
-
value: 30,
|
|
978
|
-
});
|
|
979
|
-
cdl.saveTimestamp({
|
|
980
|
-
key: 'client.ice.end',
|
|
981
|
-
value: 40,
|
|
982
|
-
});
|
|
983
|
-
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 35);
|
|
2069
|
+
// clickToInterstitialWithUserDelay = 7
|
|
2070
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
|
|
2071
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
2072
|
+
// interstitialShowedToMediaEngineReady = 50 - 10 = 40
|
|
2073
|
+
// total = 7 + 40 = 47
|
|
2074
|
+
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 47);
|
|
984
2075
|
});
|
|
985
2076
|
|
|
986
2077
|
it('calculates getTotalMediaJMTWithUserDelay correctly for guest join', () => {
|
|
987
|
-
cdl.
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
});
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
});
|
|
999
|
-
cdl.
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
cdl.
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
cdl.saveTimestamp({
|
|
1008
|
-
key: 'internal.host.meeting.participant.admitted',
|
|
1009
|
-
value: 24,
|
|
1010
|
-
});
|
|
1011
|
-
cdl.saveTimestamp({
|
|
1012
|
-
key: 'client.ice.start',
|
|
1013
|
-
value: 30,
|
|
1014
|
-
});
|
|
1015
|
-
cdl.saveTimestamp({
|
|
1016
|
-
key: 'client.ice.end',
|
|
1017
|
-
value: 40,
|
|
1018
|
-
});
|
|
1019
|
-
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 31);
|
|
2078
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 3);
|
|
2079
|
+
// clickToInterstitialWithUserDelay = 3
|
|
2080
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 8});
|
|
2081
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
2082
|
+
// interstitialShowedToMediaEngineReady = 50 - 8 = 42
|
|
2083
|
+
// total = 3 + 42 = 45
|
|
2084
|
+
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 45);
|
|
2085
|
+
});
|
|
2086
|
+
|
|
2087
|
+
it('returns undefined for getTotalMediaJMTWithUserDelay when media-engine.ready is missing', () => {
|
|
2088
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
|
|
2089
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
|
|
2090
|
+
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), undefined);
|
|
2091
|
+
});
|
|
2092
|
+
|
|
2093
|
+
it('calculates getTotalMediaJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => {
|
|
2094
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
|
|
2095
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.interstitial-window.showed', value: 10});
|
|
2096
|
+
cdl.saveTimestamp({key: 'client.media-engine.ready', value: 50});
|
|
2097
|
+
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 2147483647);
|
|
1020
2098
|
});
|
|
1021
2099
|
|
|
1022
2100
|
it('calculates getJoinConfJMT correctly', () => {
|
|
@@ -1062,6 +2140,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
1062
2140
|
});
|
|
1063
2141
|
|
|
1064
2142
|
it('calculates getClientJMT correctly', () => {
|
|
2143
|
+
cdl.saveLatency('internal.click.to.interstitial.for.client.jmt', 5);
|
|
2144
|
+
cdl.saveTimestamp({
|
|
2145
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
2146
|
+
value: 1,
|
|
2147
|
+
});
|
|
1065
2148
|
cdl.saveTimestamp({
|
|
1066
2149
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
1067
2150
|
value: 2,
|
|
@@ -1070,19 +2153,30 @@ describe('internal-plugin-metrics', () => {
|
|
|
1070
2153
|
key: 'client.locus.join.request',
|
|
1071
2154
|
value: 6,
|
|
1072
2155
|
});
|
|
2156
|
+
// showedToLocusJoinRequest = 6-1 = 5, showInterstitialTime = 2-1 = 1
|
|
2157
|
+
// clickToInterstitialForClientJmt (5) + 5 - 1 = 9
|
|
2158
|
+
assert.deepEqual(cdl.getClientJMT(), 9);
|
|
2159
|
+
});
|
|
2160
|
+
|
|
2161
|
+
it('returns undefined for getClientJMT when clickToInterstitialForClientJmt is missing', () => {
|
|
1073
2162
|
cdl.saveTimestamp({
|
|
1074
|
-
key: 'client.
|
|
1075
|
-
value:
|
|
2163
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
2164
|
+
value: 1,
|
|
1076
2165
|
});
|
|
1077
2166
|
cdl.saveTimestamp({
|
|
1078
|
-
key: 'client.
|
|
1079
|
-
value:
|
|
2167
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
2168
|
+
value: 2,
|
|
1080
2169
|
});
|
|
1081
2170
|
cdl.saveTimestamp({
|
|
1082
|
-
key: 'client.
|
|
1083
|
-
value:
|
|
2171
|
+
key: 'client.locus.join.request',
|
|
2172
|
+
value: 6,
|
|
1084
2173
|
});
|
|
1085
|
-
assert.deepEqual(cdl.getClientJMT(),
|
|
2174
|
+
assert.deepEqual(cdl.getClientJMT(), undefined);
|
|
2175
|
+
});
|
|
2176
|
+
|
|
2177
|
+
it('returns undefined for getClientJMT when interstitialJoinToLocusJoinRequest is missing', () => {
|
|
2178
|
+
cdl.saveLatency('internal.click.to.interstitial.for.client.jmt', 5);
|
|
2179
|
+
assert.deepEqual(cdl.getClientJMT(), undefined);
|
|
1086
2180
|
});
|
|
1087
2181
|
|
|
1088
2182
|
it('calculates getAudioJoinRespRxStart correctly', () => {
|
|
@@ -1134,12 +2228,16 @@ describe('internal-plugin-metrics', () => {
|
|
|
1134
2228
|
});
|
|
1135
2229
|
|
|
1136
2230
|
it('calculates getInterstitialToMediaOKJMT correctly', () => {
|
|
2231
|
+
cdl.saveTimestamp({
|
|
2232
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
2233
|
+
value: 2,
|
|
2234
|
+
});
|
|
1137
2235
|
cdl.saveTimestamp({
|
|
1138
2236
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
1139
2237
|
value: 4,
|
|
1140
2238
|
});
|
|
1141
2239
|
cdl.saveTimestamp({
|
|
1142
|
-
key: 'client.
|
|
2240
|
+
key: 'client.lobby.entered',
|
|
1143
2241
|
value: 10,
|
|
1144
2242
|
});
|
|
1145
2243
|
cdl.saveTimestamp({
|
|
@@ -1150,21 +2248,28 @@ describe('internal-plugin-metrics', () => {
|
|
|
1150
2248
|
key: 'client.ice.end',
|
|
1151
2249
|
value: 14,
|
|
1152
2250
|
});
|
|
2251
|
+
// showedToIceEnd = 14-2 = 12, showInterstitialTime = 4-2 = 2
|
|
2252
|
+
// stayLobbyTimeCappedByIceEnd = min(12,14)-10 = 2
|
|
2253
|
+
// result = 12 - 2 - 2 = 8
|
|
1153
2254
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 8);
|
|
1154
2255
|
});
|
|
1155
2256
|
|
|
1156
2257
|
it('calculates getInterstitialToMediaOKJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
2258
|
+
cdl.saveTimestamp({
|
|
2259
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
2260
|
+
value: 4,
|
|
2261
|
+
});
|
|
1157
2262
|
cdl.saveTimestamp({
|
|
1158
2263
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
1159
2264
|
value: 4,
|
|
1160
2265
|
});
|
|
1161
2266
|
cdl.saveTimestamp({
|
|
1162
|
-
key: 'client.
|
|
2267
|
+
key: 'client.lobby.entered',
|
|
1163
2268
|
value: 10,
|
|
1164
2269
|
});
|
|
1165
2270
|
cdl.saveTimestamp({
|
|
1166
2271
|
key: 'client.lobby.exited',
|
|
1167
|
-
value:
|
|
2272
|
+
value: 10,
|
|
1168
2273
|
});
|
|
1169
2274
|
cdl.saveTimestamp({
|
|
1170
2275
|
key: 'client.ice.end',
|
|
@@ -1174,6 +2279,29 @@ describe('internal-plugin-metrics', () => {
|
|
|
1174
2279
|
});
|
|
1175
2280
|
|
|
1176
2281
|
it('calculates getInterstitialToMediaOKJMT correctly without lobby', () => {
|
|
2282
|
+
cdl.saveTimestamp({
|
|
2283
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
2284
|
+
value: 2,
|
|
2285
|
+
});
|
|
2286
|
+
cdl.saveTimestamp({
|
|
2287
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
2288
|
+
value: 4,
|
|
2289
|
+
});
|
|
2290
|
+
cdl.saveTimestamp({
|
|
2291
|
+
key: 'client.ice.end',
|
|
2292
|
+
value: 14,
|
|
2293
|
+
});
|
|
2294
|
+
// showedToIceEnd = 14-2 = 12, showInterstitialTime = 4-2 = 2
|
|
2295
|
+
// stayLobbyTimeCappedByIceEnd = 0 (no lobby)
|
|
2296
|
+
// result = 12 - 2 - 0 = 10
|
|
2297
|
+
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
|
|
2298
|
+
});
|
|
2299
|
+
|
|
2300
|
+
it('calculates getInterstitialToMediaOKJMT correctly when there is no lobby and stayLobbyTime defaults to 0', () => {
|
|
2301
|
+
cdl.saveTimestamp({
|
|
2302
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
2303
|
+
value: 2,
|
|
2304
|
+
});
|
|
1177
2305
|
cdl.saveTimestamp({
|
|
1178
2306
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
1179
2307
|
value: 4,
|
|
@@ -1182,6 +2310,9 @@ describe('internal-plugin-metrics', () => {
|
|
|
1182
2310
|
key: 'client.ice.end',
|
|
1183
2311
|
value: 14,
|
|
1184
2312
|
});
|
|
2313
|
+
// showedToIceEnd = 14-2 = 12, showInterstitialTime = 4-2 = 2
|
|
2314
|
+
// stayLobbyTimeCappedByIceEnd = 0 (no lobby)
|
|
2315
|
+
// result = 12 - 2 - 0 = 10
|
|
1185
2316
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
|
|
1186
2317
|
});
|
|
1187
2318
|
|