@webex/internal-plugin-metrics 3.9.0-webinar5k.1 → 3.10.0-multi-llms.1
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/call-diagnostic/call-diagnostic-metrics-latencies.js +58 -28
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +165 -28
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +15 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +9 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +35 -3
- package/dist/types/metrics.types.d.ts +2 -1
- package/package.json +12 -13
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +68 -28
- package/src/call-diagnostic/call-diagnostic-metrics.ts +154 -2
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +14 -0
- package/src/metrics.types.ts +4 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +287 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +440 -2
- package/test/unit/spec/prelogin-metrics-batcher.ts +71 -3
|
@@ -75,6 +75,7 @@ type GetOriginOptions = {
|
|
|
75
75
|
browserLaunchMethod?: BrowserLaunchMethodType;
|
|
76
76
|
environment?: EnvironmentType;
|
|
77
77
|
newEnvironment?: NewEnvironmentType;
|
|
78
|
+
vendorId?: string;
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
type GetIdentifiersOptions = {
|
|
@@ -105,6 +106,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
105
106
|
private delayedClientFeatureEvents: DelayedClientFeatureEvent[] = [];
|
|
106
107
|
private eventErrorCache: WeakMap<any, any> = new WeakMap();
|
|
107
108
|
private isMercuryConnected = false;
|
|
109
|
+
private eventLimitTracker: Map<string, number> = new Map();
|
|
110
|
+
private eventLimitWarningsLogged: Set<string> = new Set();
|
|
108
111
|
|
|
109
112
|
// the default validator before piping an event to the batcher
|
|
110
113
|
// this function can be overridden by the user
|
|
@@ -295,6 +298,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
295
298
|
origin.clientInfo.browserLaunchMethod = options.browserLaunchMethod;
|
|
296
299
|
}
|
|
297
300
|
|
|
301
|
+
if (options?.vendorId) {
|
|
302
|
+
origin.clientInfo.vendorId = options.vendorId;
|
|
303
|
+
}
|
|
304
|
+
|
|
298
305
|
return origin;
|
|
299
306
|
}
|
|
300
307
|
|
|
@@ -665,6 +672,144 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
665
672
|
this.eventErrorCache = new WeakMap();
|
|
666
673
|
}
|
|
667
674
|
|
|
675
|
+
/**
|
|
676
|
+
* Checks if an event should be limited based on criteria defined in the event dictionary.
|
|
677
|
+
* Returns true if the event should be sent, false if it has reached its limit.
|
|
678
|
+
* @param event - The diagnostic event object
|
|
679
|
+
* @returns boolean indicating whether the event should be sent
|
|
680
|
+
*/
|
|
681
|
+
private shouldSendEvent({event}: Event): boolean {
|
|
682
|
+
const eventName = event?.name as string;
|
|
683
|
+
const correlationId = event?.identifiers?.correlationId;
|
|
684
|
+
|
|
685
|
+
if (!correlationId || correlationId === 'unknown') {
|
|
686
|
+
return true;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const limitKeyPrefix = `${eventName}:${correlationId}`;
|
|
690
|
+
|
|
691
|
+
switch (eventName) {
|
|
692
|
+
case 'client.media.render.start':
|
|
693
|
+
case 'client.media.render.stop':
|
|
694
|
+
case 'client.media.rx.start':
|
|
695
|
+
case 'client.media.rx.stop':
|
|
696
|
+
case 'client.media.tx.start':
|
|
697
|
+
case 'client.media.tx.stop': {
|
|
698
|
+
// Send only once per mediaType-correlationId pair (or mediaType-correlationId-shareInstanceId for share/share_audio)
|
|
699
|
+
const mediaType = event?.mediaType;
|
|
700
|
+
if (mediaType) {
|
|
701
|
+
if (mediaType === 'share' || mediaType === 'share_audio') {
|
|
702
|
+
const shareInstanceId = event?.shareInstanceId;
|
|
703
|
+
if (shareInstanceId) {
|
|
704
|
+
const limitKey = `${limitKeyPrefix}:${mediaType}:${shareInstanceId}`;
|
|
705
|
+
|
|
706
|
+
return this.checkAndIncrementEventCount(
|
|
707
|
+
limitKey,
|
|
708
|
+
1,
|
|
709
|
+
`${eventName} for ${mediaType} instance ${shareInstanceId}`
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
} else {
|
|
713
|
+
const limitKey = `${limitKeyPrefix}:${mediaType}`;
|
|
714
|
+
|
|
715
|
+
return this.checkAndIncrementEventCount(
|
|
716
|
+
limitKey,
|
|
717
|
+
1,
|
|
718
|
+
`${eventName} for mediaType ${mediaType}`
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
case 'client.roap-message.received':
|
|
726
|
+
case 'client.roap-message.sent': {
|
|
727
|
+
// Send only once per correlationId and roap.messageType/roap.type
|
|
728
|
+
const roapMessageType = event?.roap?.messageType || event?.roap?.type;
|
|
729
|
+
if (roapMessageType) {
|
|
730
|
+
const limitKey = `${limitKeyPrefix}:${roapMessageType}`;
|
|
731
|
+
|
|
732
|
+
return this.checkAndIncrementEventCount(
|
|
733
|
+
limitKey,
|
|
734
|
+
1,
|
|
735
|
+
`${eventName} for ROAP type ${roapMessageType}`
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
default:
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
return true;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Checks the current count for a limit key and increments if under limit.
|
|
750
|
+
* @param limitKey - The unique key for this limit combination
|
|
751
|
+
* @param maxCount - Maximum allowed count
|
|
752
|
+
* @param eventDescription - Description for logging
|
|
753
|
+
* @returns true if under limit and incremented, false if at/over limit
|
|
754
|
+
*/
|
|
755
|
+
private checkAndIncrementEventCount(
|
|
756
|
+
limitKey: string,
|
|
757
|
+
maxCount: number,
|
|
758
|
+
eventDescription: string
|
|
759
|
+
): boolean {
|
|
760
|
+
const currentCount = this.eventLimitTracker.get(limitKey) || 0;
|
|
761
|
+
|
|
762
|
+
if (currentCount >= maxCount) {
|
|
763
|
+
// Log warning only once per limit key
|
|
764
|
+
if (!this.eventLimitWarningsLogged.has(limitKey)) {
|
|
765
|
+
this.logger.log(
|
|
766
|
+
CALL_DIAGNOSTIC_LOG_IDENTIFIER,
|
|
767
|
+
`CallDiagnosticMetrics: Event limit reached for ${eventDescription}. ` +
|
|
768
|
+
`Max count ${maxCount} exceeded. Event will not be sent.`,
|
|
769
|
+
`limitKey: ${limitKey}`
|
|
770
|
+
);
|
|
771
|
+
this.eventLimitWarningsLogged.add(limitKey);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// Increment count and allow event
|
|
778
|
+
this.eventLimitTracker.set(limitKey, currentCount + 1);
|
|
779
|
+
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Clears event limit tracking
|
|
785
|
+
*/
|
|
786
|
+
public clearEventLimits(): void {
|
|
787
|
+
this.eventLimitTracker.clear();
|
|
788
|
+
this.eventLimitWarningsLogged.clear();
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Clears event limit tracking for a specific correlationId only.
|
|
793
|
+
* Keeps limits for other meetings intact.
|
|
794
|
+
*/
|
|
795
|
+
public clearEventLimitsForCorrelationId(correlationId: string): void {
|
|
796
|
+
if (!correlationId) {
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
// Keys are formatted as "eventName:correlationId:..." across all limiters.
|
|
800
|
+
const hasCorrIdAtSecondToken = (key: string) => key.split(':')[1] === correlationId;
|
|
801
|
+
for (const key of Array.from(this.eventLimitTracker.keys())) {
|
|
802
|
+
if (hasCorrIdAtSecondToken(key)) {
|
|
803
|
+
this.eventLimitTracker.delete(key);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
for (const key of Array.from(this.eventLimitWarningsLogged.values())) {
|
|
807
|
+
if (hasCorrIdAtSecondToken(key)) {
|
|
808
|
+
this.eventLimitWarningsLogged.delete(key);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
668
813
|
/**
|
|
669
814
|
* Generate error payload for Client Event
|
|
670
815
|
* @param rawError
|
|
@@ -1099,6 +1244,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1099
1244
|
);
|
|
1100
1245
|
const diagnosticEvent = this.prepareClientEvent({name, payload, options});
|
|
1101
1246
|
|
|
1247
|
+
if (!this.shouldSendEvent(diagnosticEvent)) {
|
|
1248
|
+
return Promise.resolve();
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1102
1251
|
if (options?.preLoginId) {
|
|
1103
1252
|
return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);
|
|
1104
1253
|
}
|
|
@@ -1266,8 +1415,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1266
1415
|
*/
|
|
1267
1416
|
public setDeviceInfo(device: any): void {
|
|
1268
1417
|
// This was created to fix the circular dependency between internal-plugin-device and internal-plugin-metrics
|
|
1269
|
-
this.logger.log('CallDiagnosticMetrics: @setDeviceInfo called',
|
|
1270
|
-
|
|
1418
|
+
this.logger.log('CallDiagnosticMetrics: @setDeviceInfo called', {
|
|
1419
|
+
userId: device?.userId,
|
|
1420
|
+
deviceId: device?.url,
|
|
1421
|
+
orgId: device?.orgId,
|
|
1422
|
+
});
|
|
1271
1423
|
this.device = device;
|
|
1272
1424
|
}
|
|
1273
1425
|
}
|
|
@@ -239,6 +239,20 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
239
239
|
|
|
240
240
|
// Set upgradeChannel to 'gold' if buildType is 'prod', otherwise to the buildType value
|
|
241
241
|
const upgradeChannel = buildType === 'prod' ? 'gold' : buildType;
|
|
242
|
+
if (webex.devicemanager) {
|
|
243
|
+
const pairedDevice = webex.devicemanager.getPairedDevice();
|
|
244
|
+
if (pairedDevice) {
|
|
245
|
+
const devicePayload = {
|
|
246
|
+
deviceId: pairedDevice.deviceInfo?.id,
|
|
247
|
+
devicePairingType: webex.devicemanager.getPairedMethod(),
|
|
248
|
+
deviceURL: pairedDevice.url,
|
|
249
|
+
isPersonalDevice: pairedDevice.mode === 'personal',
|
|
250
|
+
productName: pairedDevice.devices[0]?.productName,
|
|
251
|
+
};
|
|
252
|
+
item.eventPayload.event.pairingState = 'paired';
|
|
253
|
+
item.eventPayload.event.pairedDevice = devicePayload;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
242
256
|
|
|
243
257
|
const origin: Partial<Event['origin']> = {
|
|
244
258
|
buildType,
|
package/src/metrics.types.ts
CHANGED
|
@@ -138,6 +138,7 @@ export type SubmitClientEventOptions = {
|
|
|
138
138
|
triggeredTime?: string;
|
|
139
139
|
emailInput?: ClientEmailInput;
|
|
140
140
|
userNameInput?: ClientUserNameInput;
|
|
141
|
+
vendorId?: string;
|
|
141
142
|
};
|
|
142
143
|
|
|
143
144
|
export type SubmitMQEOptions = {
|
|
@@ -160,7 +161,9 @@ export type InternalEvent = {
|
|
|
160
161
|
| 'internal.client.meeting.interstitial-window.showed'
|
|
161
162
|
| 'internal.client.interstitial-window.click.joinbutton'
|
|
162
163
|
| 'internal.client.add-media.turn-discovery.start'
|
|
163
|
-
| 'internal.client.add-media.turn-discovery.end'
|
|
164
|
+
| 'internal.client.add-media.turn-discovery.end'
|
|
165
|
+
| 'internal.client.share.initiated'
|
|
166
|
+
| 'internal.client.share.stopped';
|
|
164
167
|
|
|
165
168
|
payload?: never;
|
|
166
169
|
options?: never;
|
|
@@ -130,6 +130,96 @@ describe('internal-plugin-metrics', () => {
|
|
|
130
130
|
assert.deepEqual(res2, undefined);
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
+
describe('getDiffBetweenTimestamps with clamping', () => {
|
|
134
|
+
it('should apply default clamping (min: 0, max: 2147483647) when no clampValues provided', () => {
|
|
135
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
136
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
137
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
|
|
138
|
+
assert.deepEqual(res, 40);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should return diff without clamping when value is within range', () => {
|
|
142
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
143
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
144
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
145
|
+
minimum: 0,
|
|
146
|
+
maximum: 100
|
|
147
|
+
});
|
|
148
|
+
assert.deepEqual(res, 40);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should clamp to minimum when diff is below minimum', () => {
|
|
152
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
|
|
153
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
|
|
154
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
155
|
+
minimum: 10,
|
|
156
|
+
maximum: 100
|
|
157
|
+
});
|
|
158
|
+
assert.deepEqual(res, 10);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should clamp to maximum when diff is above maximum', () => {
|
|
162
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
163
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 210});
|
|
164
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
165
|
+
minimum: 0,
|
|
166
|
+
maximum: 100
|
|
167
|
+
});
|
|
168
|
+
assert.deepEqual(res, 100);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should use default minimum of 0 when only maximum is specified', () => {
|
|
172
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
|
|
173
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
|
|
174
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
175
|
+
maximum: 100
|
|
176
|
+
});
|
|
177
|
+
assert.deepEqual(res, 0);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should not clamp maximum when maximum is undefined', () => {
|
|
181
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
182
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 2000});
|
|
183
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
184
|
+
minimum: 5
|
|
185
|
+
});
|
|
186
|
+
assert.deepEqual(res, 1990);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should handle negative differences correctly with clamping', () => {
|
|
190
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 100});
|
|
191
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
192
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
193
|
+
minimum: 10,
|
|
194
|
+
maximum: 1000
|
|
195
|
+
});
|
|
196
|
+
assert.deepEqual(res, 10);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should return undefined when timestamps are missing even with clamping', () => {
|
|
200
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
201
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
202
|
+
minimum: 0,
|
|
203
|
+
maximum: 100
|
|
204
|
+
});
|
|
205
|
+
assert.deepEqual(res, undefined);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should apply default minimum clamping (0) when no clampValues provided and diff is negative', () => {
|
|
209
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 100});
|
|
210
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
211
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
|
|
212
|
+
assert.deepEqual(res, 0);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('should clamp the value when a number greater than 2147483647', () => {
|
|
216
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 0});
|
|
217
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 2147483648});
|
|
218
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
|
|
219
|
+
assert.deepEqual(res, 2147483647);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
133
223
|
it('calculates getMeetingInfoReqResp correctly', () => {
|
|
134
224
|
cdl.saveTimestamp({key: 'internal.client.meetinginfo.request', value: 10});
|
|
135
225
|
cdl.saveTimestamp({key: 'internal.client.meetinginfo.response', value: 20});
|
|
@@ -227,6 +317,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
227
317
|
|
|
228
318
|
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 321);
|
|
229
319
|
});
|
|
320
|
+
|
|
321
|
+
it('returns the correct number when it is greater than 2147483647', () => {
|
|
322
|
+
cdl.saveLatency('internal.refresh.captcha.time', 4294967400);
|
|
323
|
+
|
|
324
|
+
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 2147483647);
|
|
325
|
+
});
|
|
230
326
|
});
|
|
231
327
|
|
|
232
328
|
describe('getReachabilityClustersReqResp', () => {
|
|
@@ -245,6 +341,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
245
341
|
|
|
246
342
|
assert.deepEqual(cdl.getReachabilityClustersReqResp(), 321);
|
|
247
343
|
});
|
|
344
|
+
|
|
345
|
+
it('returns the correct number when it is greater than 2147483647', () => {
|
|
346
|
+
cdl.saveLatency('internal.get.cluster.time', 4294967400);
|
|
347
|
+
|
|
348
|
+
assert.deepEqual(cdl.getReachabilityClustersReqResp(), 2147483647);
|
|
349
|
+
});
|
|
248
350
|
});
|
|
249
351
|
|
|
250
352
|
describe('getExchangeCITokenJMT', () => {
|
|
@@ -263,6 +365,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
263
365
|
|
|
264
366
|
assert.deepEqual(cdl.getExchangeCITokenJMT(), 321);
|
|
265
367
|
});
|
|
368
|
+
|
|
369
|
+
it('returns the correct number when it is greater than 2147483647', () => {
|
|
370
|
+
cdl.saveLatency('internal.exchange.ci.token.time', 4294967400);
|
|
371
|
+
|
|
372
|
+
assert.deepEqual(cdl.getExchangeCITokenJMT(), 2147483647);
|
|
373
|
+
});
|
|
266
374
|
});
|
|
267
375
|
|
|
268
376
|
describe('saveTimestamp', () => {
|
|
@@ -416,6 +524,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
416
524
|
assert.deepEqual(cdl.getPageJMT(), 10);
|
|
417
525
|
});
|
|
418
526
|
|
|
527
|
+
it('calculates getPageJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
528
|
+
cdl.saveLatency('internal.client.pageJMT', 2147483648);
|
|
529
|
+
assert.deepEqual(cdl.getPageJMT(), 2147483647);
|
|
530
|
+
});
|
|
531
|
+
|
|
419
532
|
it('calculates getClickToInterstitial correctly', () => {
|
|
420
533
|
cdl.saveTimestamp({
|
|
421
534
|
key: 'internal.client.meeting.click.joinbutton',
|
|
@@ -446,6 +559,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
446
559
|
assert.deepEqual(cdl.getClickToInterstitial(), 0);
|
|
447
560
|
});
|
|
448
561
|
|
|
562
|
+
it('calculates getClickToInterstitial without join button timestamp when it is greater than MAX_INTEGER', () => {
|
|
563
|
+
cdl.saveLatency('internal.click.to.interstitial', 2147483648);
|
|
564
|
+
assert.deepEqual(cdl.getClickToInterstitial(), 2147483647);
|
|
565
|
+
});
|
|
566
|
+
|
|
449
567
|
it('calculates getClickToInterstitialWithUserDelay correctly', () => {
|
|
450
568
|
cdl.saveTimestamp({
|
|
451
569
|
key: 'internal.client.meeting.click.joinbutton',
|
|
@@ -476,6 +594,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
476
594
|
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 0);
|
|
477
595
|
});
|
|
478
596
|
|
|
597
|
+
it('calculates getClickToInterstitialWithUserDelay without join button timestamp when it is greater than MAX_INTEGER', () => {
|
|
598
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
|
|
599
|
+
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 2147483647);
|
|
600
|
+
});
|
|
601
|
+
|
|
479
602
|
it('calculates getInterstitialToJoinOK correctly', () => {
|
|
480
603
|
cdl.saveTimestamp({
|
|
481
604
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
@@ -584,6 +707,19 @@ describe('internal-plugin-metrics', () => {
|
|
|
584
707
|
assert.deepEqual(cdl.getTotalJMT(), undefined);
|
|
585
708
|
});
|
|
586
709
|
|
|
710
|
+
it('calculates getTotalJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
711
|
+
cdl.saveTimestamp({
|
|
712
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
713
|
+
value: 5,
|
|
714
|
+
});
|
|
715
|
+
cdl.saveTimestamp({
|
|
716
|
+
key: 'client.locus.join.response',
|
|
717
|
+
value: 40,
|
|
718
|
+
});
|
|
719
|
+
cdl.saveLatency('internal.click.to.interstitial', 2147483648);
|
|
720
|
+
assert.deepEqual(cdl.getTotalJMT(), 2147483647);
|
|
721
|
+
});
|
|
722
|
+
|
|
587
723
|
it('calculates getTotalJMTWithUserDelay correctly', () => {
|
|
588
724
|
cdl.saveTimestamp({
|
|
589
725
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
@@ -656,6 +792,19 @@ describe('internal-plugin-metrics', () => {
|
|
|
656
792
|
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), undefined);
|
|
657
793
|
});
|
|
658
794
|
|
|
795
|
+
it('calculates getTotalJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => {
|
|
796
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648);
|
|
797
|
+
cdl.saveTimestamp({
|
|
798
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
799
|
+
value: 20,
|
|
800
|
+
});
|
|
801
|
+
cdl.saveTimestamp({
|
|
802
|
+
key: 'client.locus.join.response',
|
|
803
|
+
value: 40,
|
|
804
|
+
});
|
|
805
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 2147483647);
|
|
806
|
+
});
|
|
807
|
+
|
|
659
808
|
it('calculates getTotalMediaJMT correctly', () => {
|
|
660
809
|
cdl.saveTimestamp({
|
|
661
810
|
key: 'internal.client.meeting.click.joinbutton',
|
|
@@ -692,6 +841,42 @@ describe('internal-plugin-metrics', () => {
|
|
|
692
841
|
assert.deepEqual(cdl.getTotalMediaJMT(), 27);
|
|
693
842
|
});
|
|
694
843
|
|
|
844
|
+
it('calculates getTotalMediaJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
845
|
+
cdl.saveTimestamp({
|
|
846
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
847
|
+
value: 5,
|
|
848
|
+
});
|
|
849
|
+
cdl.saveTimestamp({
|
|
850
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
851
|
+
value: 8,
|
|
852
|
+
});
|
|
853
|
+
cdl.saveTimestamp({
|
|
854
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
855
|
+
value: 10,
|
|
856
|
+
});
|
|
857
|
+
cdl.saveTimestamp({
|
|
858
|
+
key: 'client.locus.join.request',
|
|
859
|
+
value: 12,
|
|
860
|
+
});
|
|
861
|
+
cdl.saveTimestamp({
|
|
862
|
+
key: 'client.locus.join.response',
|
|
863
|
+
value: 2147483700,
|
|
864
|
+
});
|
|
865
|
+
cdl.saveTimestamp({
|
|
866
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
867
|
+
value: 2147483800,
|
|
868
|
+
});
|
|
869
|
+
cdl.saveTimestamp({
|
|
870
|
+
key: 'client.ice.start',
|
|
871
|
+
value: 30,
|
|
872
|
+
});
|
|
873
|
+
cdl.saveTimestamp({
|
|
874
|
+
key: 'client.ice.end',
|
|
875
|
+
value: 100,
|
|
876
|
+
});
|
|
877
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
|
|
878
|
+
});
|
|
879
|
+
|
|
695
880
|
it('calculates getTotalMediaJMT correctly with allowMediaInLobby true', () => {
|
|
696
881
|
cdl.saveTimestamp({
|
|
697
882
|
key: 'internal.client.meeting.click.joinbutton',
|
|
@@ -729,6 +914,43 @@ describe('internal-plugin-metrics', () => {
|
|
|
729
914
|
assert.deepEqual(cdl.getTotalMediaJMT(), 31);
|
|
730
915
|
});
|
|
731
916
|
|
|
917
|
+
it('calculates getTotalMediaJMT correctly with allowMediaInLobby true and it is greater than MAX_INTEGER', () => {
|
|
918
|
+
cdl.saveTimestamp({
|
|
919
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
920
|
+
value: 5,
|
|
921
|
+
options: {meetingId: 'meeting-id'},
|
|
922
|
+
});
|
|
923
|
+
cdl.saveTimestamp({
|
|
924
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
925
|
+
value: 100,
|
|
926
|
+
});
|
|
927
|
+
cdl.saveTimestamp({
|
|
928
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
929
|
+
value: 1000,
|
|
930
|
+
});
|
|
931
|
+
cdl.saveTimestamp({
|
|
932
|
+
key: 'client.locus.join.request',
|
|
933
|
+
value: 2000,
|
|
934
|
+
});
|
|
935
|
+
cdl.saveTimestamp({
|
|
936
|
+
key: 'client.locus.join.response',
|
|
937
|
+
value: 2147483700,
|
|
938
|
+
});
|
|
939
|
+
cdl.saveTimestamp({
|
|
940
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
941
|
+
value: 2147483800,
|
|
942
|
+
});
|
|
943
|
+
cdl.saveTimestamp({
|
|
944
|
+
key: 'client.ice.start',
|
|
945
|
+
value: 2147483900,
|
|
946
|
+
});
|
|
947
|
+
cdl.saveTimestamp({
|
|
948
|
+
key: 'client.ice.end',
|
|
949
|
+
value: 4294967400,
|
|
950
|
+
});
|
|
951
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 2147483647);
|
|
952
|
+
});
|
|
953
|
+
|
|
732
954
|
it('calculates getTotalMediaJMTWithUserDelay correctly', () => {
|
|
733
955
|
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
|
|
734
956
|
cdl.saveTimestamp({
|
|
@@ -814,6 +1036,28 @@ describe('internal-plugin-metrics', () => {
|
|
|
814
1036
|
assert.deepEqual(cdl.getJoinConfJMT(), 20);
|
|
815
1037
|
});
|
|
816
1038
|
|
|
1039
|
+
it('calculates getJoinConfJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
1040
|
+
// Since both getJoinReqResp and getICESetupTime are individually clamped to 1200000,
|
|
1041
|
+
// the maximum possible sum is 2400000, which is less than MAX_INTEGER (2147483647).
|
|
1042
|
+
// This test should verify that the final clamping works by mocking the intermediate methods
|
|
1043
|
+
// to return values that would sum to more than MAX_INTEGER.
|
|
1044
|
+
|
|
1045
|
+
const originalGetJoinReqResp = cdl.getJoinReqResp;
|
|
1046
|
+
const originalGetICESetupTime = cdl.getICESetupTime;
|
|
1047
|
+
|
|
1048
|
+
// Mock the methods to return large values that would exceed MAX_INTEGER when summed
|
|
1049
|
+
cdl.getJoinReqResp = () => 1500000000;
|
|
1050
|
+
cdl.getICESetupTime = () => 1000000000;
|
|
1051
|
+
|
|
1052
|
+
const result = cdl.getJoinConfJMT();
|
|
1053
|
+
|
|
1054
|
+
// Restore original methods
|
|
1055
|
+
cdl.getJoinReqResp = originalGetJoinReqResp;
|
|
1056
|
+
cdl.getICESetupTime = originalGetICESetupTime;
|
|
1057
|
+
|
|
1058
|
+
assert.deepEqual(result, 2147483647);
|
|
1059
|
+
});
|
|
1060
|
+
|
|
817
1061
|
it('calculates getClientJMT correctly', () => {
|
|
818
1062
|
cdl.saveTimestamp({
|
|
819
1063
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
@@ -906,6 +1150,26 @@ describe('internal-plugin-metrics', () => {
|
|
|
906
1150
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 8);
|
|
907
1151
|
});
|
|
908
1152
|
|
|
1153
|
+
it('calculates getInterstitialToMediaOKJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
1154
|
+
cdl.saveTimestamp({
|
|
1155
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
1156
|
+
value: 4,
|
|
1157
|
+
});
|
|
1158
|
+
cdl.saveTimestamp({
|
|
1159
|
+
key: 'client.locus.join.response',
|
|
1160
|
+
value: 10,
|
|
1161
|
+
});
|
|
1162
|
+
cdl.saveTimestamp({
|
|
1163
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
1164
|
+
value: 12,
|
|
1165
|
+
});
|
|
1166
|
+
cdl.saveTimestamp({
|
|
1167
|
+
key: 'client.ice.end',
|
|
1168
|
+
value: 2147483700,
|
|
1169
|
+
});
|
|
1170
|
+
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 2147483647);
|
|
1171
|
+
});
|
|
1172
|
+
|
|
909
1173
|
it('calculates getInterstitialToMediaOKJMT correctly without lobby', () => {
|
|
910
1174
|
cdl.saveTimestamp({
|
|
911
1175
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
@@ -918,6 +1182,18 @@ describe('internal-plugin-metrics', () => {
|
|
|
918
1182
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
|
|
919
1183
|
});
|
|
920
1184
|
|
|
1185
|
+
it('calculates getShareDuration correctly', () => {
|
|
1186
|
+
cdl.saveTimestamp({
|
|
1187
|
+
key: 'internal.client.share.initiated',
|
|
1188
|
+
value: 5,
|
|
1189
|
+
});
|
|
1190
|
+
cdl.saveTimestamp({
|
|
1191
|
+
key: 'internal.client.share.stopped',
|
|
1192
|
+
value: 7,
|
|
1193
|
+
});
|
|
1194
|
+
assert.deepEqual(cdl.getShareDuration(), 2);
|
|
1195
|
+
});
|
|
1196
|
+
|
|
921
1197
|
describe('calculates getU2CTime correctly', () => {
|
|
922
1198
|
it('returns undefined when no precomputed value available', () => {
|
|
923
1199
|
assert.deepEqual(cdl.getU2CTime(), undefined);
|
|
@@ -941,6 +1217,11 @@ describe('internal-plugin-metrics', () => {
|
|
|
941
1217
|
assert.deepEqual(cdl.getDownloadTimeJMT(), 1000);
|
|
942
1218
|
});
|
|
943
1219
|
|
|
1220
|
+
it('calculates getDownloadTimeJMT correctly when it is greater than MAX_INTEGER', () => {
|
|
1221
|
+
cdl.saveLatency('internal.download.time', 2147483648);
|
|
1222
|
+
assert.deepEqual(cdl.getDownloadTimeJMT(), 2147483647);
|
|
1223
|
+
});
|
|
1224
|
+
|
|
944
1225
|
describe('getOtherAppApiReqResp', () => {
|
|
945
1226
|
it('returns undefined when no precomputed value available', () => {
|
|
946
1227
|
assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
|
|
@@ -963,6 +1244,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
963
1244
|
|
|
964
1245
|
assert.deepEqual(cdl.getOtherAppApiReqResp(), 321);
|
|
965
1246
|
});
|
|
1247
|
+
|
|
1248
|
+
it('returns the correct number when it is greater than 2147483647', () => {
|
|
1249
|
+
cdl.saveLatency('internal.other.app.api.time', 4294967400);
|
|
1250
|
+
|
|
1251
|
+
assert.deepEqual(cdl.getOtherAppApiReqResp(), 2147483647);
|
|
1252
|
+
});
|
|
966
1253
|
});
|
|
967
1254
|
});
|
|
968
1255
|
});
|