@webex/plugin-meetings 3.0.0-beta.357 → 3.0.0-beta.358
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +3 -3
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/statsAnalyzer/index.js +1 -1
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +13 -10
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +19 -19
- package/src/constants.ts +1 -1
- package/src/statsAnalyzer/index.ts +2 -2
- package/src/statsAnalyzer/mqaUtil.ts +15 -14
- package/test/unit/spec/stats-analyzer/index.js +181 -30
|
@@ -1017,7 +1017,7 @@ export declare const AVAILABLE_RESOLUTIONS: {
|
|
|
1017
1017
|
};
|
|
1018
1018
|
};
|
|
1019
1019
|
};
|
|
1020
|
-
export declare const
|
|
1020
|
+
export declare const MQA_INTERVAL = 60000;
|
|
1021
1021
|
export declare const MEDIA_DEVICES: {
|
|
1022
1022
|
MICROPHONE: string;
|
|
1023
1023
|
SPEAKER: string;
|
package/dist/webinar/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
|
|
|
62
62
|
updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
|
|
63
63
|
this.set('canManageWebcast', canManageWebcast);
|
|
64
64
|
},
|
|
65
|
-
version: "3.0.0-beta.
|
|
65
|
+
version: "3.0.0-beta.358"
|
|
66
66
|
});
|
|
67
67
|
var _default = Webinar;
|
|
68
68
|
exports.default = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.358",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
|
|
6
6
|
"contributors": [
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@peculiar/webcrypto": "^1.4.3",
|
|
36
|
-
"@webex/plugin-meetings": "3.0.0-beta.
|
|
37
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
38
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
39
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
40
|
-
"@webex/test-helper-retry": "3.0.0-beta.
|
|
41
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
36
|
+
"@webex/plugin-meetings": "3.0.0-beta.358",
|
|
37
|
+
"@webex/test-helper-chai": "3.0.0-beta.358",
|
|
38
|
+
"@webex/test-helper-mocha": "3.0.0-beta.358",
|
|
39
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.358",
|
|
40
|
+
"@webex/test-helper-retry": "3.0.0-beta.358",
|
|
41
|
+
"@webex/test-helper-test-users": "3.0.0-beta.358",
|
|
42
42
|
"chai": "^4.3.4",
|
|
43
43
|
"chai-as-promised": "^7.1.1",
|
|
44
44
|
"jsdom-global": "3.0.2",
|
|
@@ -47,19 +47,19 @@
|
|
|
47
47
|
"typescript": "^4.7.4"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@webex/common": "3.0.0-beta.
|
|
50
|
+
"@webex/common": "3.0.0-beta.358",
|
|
51
51
|
"@webex/internal-media-core": "2.2.7",
|
|
52
|
-
"@webex/internal-plugin-conversation": "3.0.0-beta.
|
|
53
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
54
|
-
"@webex/internal-plugin-llm": "3.0.0-beta.
|
|
55
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
56
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
57
|
-
"@webex/internal-plugin-support": "3.0.0-beta.
|
|
58
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
59
|
-
"@webex/media-helpers": "3.0.0-beta.
|
|
60
|
-
"@webex/plugin-people": "3.0.0-beta.
|
|
61
|
-
"@webex/plugin-rooms": "3.0.0-beta.
|
|
62
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
52
|
+
"@webex/internal-plugin-conversation": "3.0.0-beta.358",
|
|
53
|
+
"@webex/internal-plugin-device": "3.0.0-beta.358",
|
|
54
|
+
"@webex/internal-plugin-llm": "3.0.0-beta.358",
|
|
55
|
+
"@webex/internal-plugin-mercury": "3.0.0-beta.358",
|
|
56
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.358",
|
|
57
|
+
"@webex/internal-plugin-support": "3.0.0-beta.358",
|
|
58
|
+
"@webex/internal-plugin-user": "3.0.0-beta.358",
|
|
59
|
+
"@webex/media-helpers": "3.0.0-beta.358",
|
|
60
|
+
"@webex/plugin-people": "3.0.0-beta.358",
|
|
61
|
+
"@webex/plugin-rooms": "3.0.0-beta.358",
|
|
62
|
+
"@webex/webex-core": "3.0.0-beta.358",
|
|
63
63
|
"ampersand-collection": "^2.0.2",
|
|
64
64
|
"bowser": "^2.11.0",
|
|
65
65
|
"btoa": "^1.2.1",
|
package/src/constants.ts
CHANGED
|
@@ -1236,7 +1236,7 @@ export const AVAILABLE_RESOLUTIONS = {
|
|
|
1236
1236
|
* mqa Interval for sending stats metrics
|
|
1237
1237
|
*/
|
|
1238
1238
|
|
|
1239
|
-
export const
|
|
1239
|
+
export const MQA_INTERVAL = 60000; // mqa analyzer interval its fixed to 60000
|
|
1240
1240
|
|
|
1241
1241
|
export const MEDIA_DEVICES = {
|
|
1242
1242
|
MICROPHONE: 'microphone',
|
|
@@ -7,7 +7,7 @@ import EventsScope from '../common/events/events-scope';
|
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_GET_STATS_FILTER,
|
|
9
9
|
STATS,
|
|
10
|
-
|
|
10
|
+
MQA_INTERVAL,
|
|
11
11
|
NETWORK_TYPE,
|
|
12
12
|
MEDIA_DEVICES,
|
|
13
13
|
_UNKNOWN_,
|
|
@@ -299,7 +299,7 @@ export class StatsAnalyzer extends EventsScope {
|
|
|
299
299
|
this.sendMqaData();
|
|
300
300
|
this.mqaInterval = setInterval(() => {
|
|
301
301
|
this.sendMqaData();
|
|
302
|
-
},
|
|
302
|
+
}, MQA_INTERVAL);
|
|
303
303
|
});
|
|
304
304
|
}
|
|
305
305
|
|
|
@@ -29,13 +29,14 @@ export const getAudioReceiverMqa = ({audioReceiver, statsResults, lastMqaDataSen
|
|
|
29
29
|
// add rtpPacket info inside common as also for call analyzer
|
|
30
30
|
audioReceiver.common.rtpPackets =
|
|
31
31
|
statsResults[mediaType][sendrecvType].totalPacketsReceived - lastPacketsReceived || 0;
|
|
32
|
+
audioReceiver.streams[0].common.rtpPackets = audioReceiver.common.rtpPackets;
|
|
33
|
+
|
|
32
34
|
// Hop by hop are numbers and not percentage so we compare on what we sent the last min
|
|
33
35
|
// collect the packets received for the last min
|
|
34
|
-
|
|
35
|
-
audioReceiver.common.mediaHopByHopLost =
|
|
36
|
-
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
37
|
-
audioReceiver.common.rtpHopByHopLost =
|
|
36
|
+
const totalPacketsLost =
|
|
38
37
|
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
38
|
+
audioReceiver.common.mediaHopByHopLost = totalPacketsLost;
|
|
39
|
+
audioReceiver.common.rtpHopByHopLost = totalPacketsLost;
|
|
39
40
|
|
|
40
41
|
audioReceiver.streams[0].common.maxRtpJitter =
|
|
41
42
|
// @ts-ignore
|
|
@@ -49,6 +50,7 @@ export const getAudioReceiverMqa = ({audioReceiver, statsResults, lastMqaDataSen
|
|
|
49
50
|
statsResults[mediaType][sendrecvType].fecPacketsReceived -
|
|
50
51
|
lastFecPacketsReceived -
|
|
51
52
|
(statsResults[mediaType][sendrecvType].fecPacketsDiscarded - lastFecPacketsDiscarded);
|
|
53
|
+
audioReceiver.common.fecPackets = fecRecovered || 0;
|
|
52
54
|
|
|
53
55
|
audioReceiver.streams[0].common.rtpEndToEndLost =
|
|
54
56
|
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost - fecRecovered || 0;
|
|
@@ -105,7 +107,7 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent, m
|
|
|
105
107
|
statsResults[mediaType][sendrecvType].totalPacketsLostOnReceiver - lastPacketsLost;
|
|
106
108
|
|
|
107
109
|
audioSender.common.remoteLossRate =
|
|
108
|
-
|
|
110
|
+
audioSender.common.rtpPackets > 0
|
|
109
111
|
? (totalpacketsLostForaMin * 100) / audioSender.common.rtpPackets
|
|
110
112
|
: 0; // This is the packets sent with in last min || 0;
|
|
111
113
|
|
|
@@ -156,16 +158,15 @@ export const getVideoReceiverMqa = ({videoReceiver, statsResults, lastMqaDataSen
|
|
|
156
158
|
statsResults[mediaType][sendrecvType].totalPacketsReceived - lastPacketsReceived || 0;
|
|
157
159
|
videoReceiver.streams[0].common.rtpPackets = videoReceiver.common.rtpPackets;
|
|
158
160
|
|
|
159
|
-
|
|
160
|
-
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
161
|
-
|
|
162
|
-
// Hope by hop are numbers and not percentage so we compare on what we sent the last min
|
|
161
|
+
// Hop by hop are numbers and not percentage so we compare on what we sent the last min
|
|
163
162
|
// this is including packet lost
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
const totalPacketsLost =
|
|
164
|
+
statsResults[mediaType][sendrecvType].totalPacketsLost - lastPacketsLost || 0;
|
|
165
|
+
videoReceiver.common.mediaHopByHopLost = totalPacketsLost;
|
|
166
|
+
videoReceiver.common.rtpHopByHopLost = totalPacketsLost;
|
|
166
167
|
|
|
167
168
|
// End to end packetloss is after recovery
|
|
168
|
-
videoReceiver.streams[0].common.rtpEndToEndLost =
|
|
169
|
+
videoReceiver.streams[0].common.rtpEndToEndLost = totalPacketsLost;
|
|
169
170
|
|
|
170
171
|
// calculate this values
|
|
171
172
|
|
|
@@ -249,8 +250,8 @@ export const getVideoSenderMqa = ({videoSender, statsResults, lastMqaDataSent, m
|
|
|
249
250
|
statsResults[mediaType][sendrecvType].totalPacketsLostOnReceiver - lastPacketsLost;
|
|
250
251
|
|
|
251
252
|
videoSender.common.remoteLossRate =
|
|
252
|
-
|
|
253
|
-
? (totalpacketsLostForaMin * 100) /
|
|
253
|
+
videoSender.common.rtpPackets > 0
|
|
254
|
+
? (totalpacketsLostForaMin * 100) / videoSender.common.rtpPackets
|
|
254
255
|
: 0; // This is the packets sent with in last min || 0;
|
|
255
256
|
|
|
256
257
|
videoSender.common.maxRoundTripTime =
|
|
@@ -7,7 +7,7 @@ import {ConnectionState} from '@webex/internal-media-core';
|
|
|
7
7
|
import {StatsAnalyzer, EVENTS} from '../../../../src/statsAnalyzer';
|
|
8
8
|
import NetworkQualityMonitor from '../../../../src/networkQualityMonitor';
|
|
9
9
|
import testUtils from '../../../utils/testUtils';
|
|
10
|
-
import {MEDIA_DEVICES, _UNKNOWN_} from '@webex/plugin-meetings/src/constants';
|
|
10
|
+
import {MEDIA_DEVICES, MQA_INTERVAL, _UNKNOWN_} from '@webex/plugin-meetings/src/constants';
|
|
11
11
|
import LoggerProxy from '../../../../src/common/logs/logger-proxy';
|
|
12
12
|
import LoggerConfig from '../../../../src/common/logs/logger-config';
|
|
13
13
|
|
|
@@ -285,8 +285,12 @@ describe('plugin-meetings', () => {
|
|
|
285
285
|
report: [
|
|
286
286
|
{
|
|
287
287
|
type: 'outbound-rtp',
|
|
288
|
-
packetsSent: 0,
|
|
289
288
|
bytesSent: 1,
|
|
289
|
+
packetsSent: 0,
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
type: 'remote-inbound-rtp',
|
|
293
|
+
packetsLost: 0,
|
|
290
294
|
},
|
|
291
295
|
{
|
|
292
296
|
type: 'candidate-pair',
|
|
@@ -311,8 +315,14 @@ describe('plugin-meetings', () => {
|
|
|
311
315
|
report: [
|
|
312
316
|
{
|
|
313
317
|
type: 'inbound-rtp',
|
|
314
|
-
packetsReceived: 0,
|
|
315
318
|
bytesReceived: 1,
|
|
319
|
+
fecPacketsDiscarded: 0,
|
|
320
|
+
fecPacketsReceived: 0,
|
|
321
|
+
packetsLost: 0,
|
|
322
|
+
packetsReceived: 0,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
type: 'remote-outbound-rtp',
|
|
316
326
|
},
|
|
317
327
|
{
|
|
318
328
|
type: 'candidate-pair',
|
|
@@ -340,8 +350,13 @@ describe('plugin-meetings', () => {
|
|
|
340
350
|
report: [
|
|
341
351
|
{
|
|
342
352
|
type: 'outbound-rtp',
|
|
343
|
-
framesSent: 1500,
|
|
344
353
|
bytesSent: 1,
|
|
354
|
+
framesSent: 0,
|
|
355
|
+
packetsSent: 0,
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
type: 'remote-inbound-rtp',
|
|
359
|
+
packetsLost: 0,
|
|
345
360
|
},
|
|
346
361
|
{
|
|
347
362
|
type: 'candidate-pair',
|
|
@@ -366,11 +381,16 @@ describe('plugin-meetings', () => {
|
|
|
366
381
|
report: [
|
|
367
382
|
{
|
|
368
383
|
type: 'inbound-rtp',
|
|
369
|
-
framesDecoded: 0,
|
|
370
384
|
bytesReceived: 1,
|
|
371
385
|
frameHeight: 720,
|
|
372
386
|
frameWidth: 1280,
|
|
373
|
-
|
|
387
|
+
framesDecoded: 0,
|
|
388
|
+
framesReceived: 0,
|
|
389
|
+
packetsLost: 0,
|
|
390
|
+
packetsReceived: 0,
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
type: 'remote-outbound-rtp',
|
|
374
394
|
},
|
|
375
395
|
{
|
|
376
396
|
type: 'candidate-pair',
|
|
@@ -448,21 +468,27 @@ describe('plugin-meetings', () => {
|
|
|
448
468
|
await testUtils.flushPromises();
|
|
449
469
|
};
|
|
450
470
|
|
|
451
|
-
const mergeProperties = (
|
|
471
|
+
const mergeProperties = (
|
|
472
|
+
target,
|
|
473
|
+
properties,
|
|
474
|
+
keyValue = 'fake-candidate-id',
|
|
475
|
+
matchKey = 'type',
|
|
476
|
+
matchValue = 'local-candidate'
|
|
477
|
+
) => {
|
|
452
478
|
for (let key in target) {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}
|
|
479
|
+
if (target.hasOwnProperty(key)) {
|
|
480
|
+
if (typeof target[key] === 'object') {
|
|
481
|
+
mergeProperties(target[key], properties, keyValue, matchKey, matchValue);
|
|
482
|
+
}
|
|
483
|
+
if (key === 'id' && target[key] === keyValue && target[matchKey] === matchValue) {
|
|
484
|
+
Object.assign(target, properties);
|
|
460
485
|
}
|
|
486
|
+
}
|
|
461
487
|
}
|
|
462
|
-
|
|
488
|
+
};
|
|
463
489
|
|
|
464
|
-
const progressTime = async () => {
|
|
465
|
-
await clock.tickAsync(
|
|
490
|
+
const progressTime = async (time = initialConfig.analyzerInterval) => {
|
|
491
|
+
await clock.tickAsync(time);
|
|
466
492
|
await testUtils.flushPromises();
|
|
467
493
|
};
|
|
468
494
|
|
|
@@ -590,10 +616,10 @@ describe('plugin-meetings', () => {
|
|
|
590
616
|
});
|
|
591
617
|
|
|
592
618
|
it('emits the correct transportType in MEDIA_QUALITY events when using a TURN server', async () => {
|
|
593
|
-
fakeStats.audio.senders[0].report[
|
|
594
|
-
fakeStats.video.senders[0].report[
|
|
595
|
-
fakeStats.audio.receivers[0].report[
|
|
596
|
-
fakeStats.video.receivers[0].report[
|
|
619
|
+
fakeStats.audio.senders[0].report[4].relayProtocol = 'tls';
|
|
620
|
+
fakeStats.video.senders[0].report[4].relayProtocol = 'tls';
|
|
621
|
+
fakeStats.audio.receivers[0].report[4].relayProtocol = 'tls';
|
|
622
|
+
fakeStats.video.receivers[0].report[4].relayProtocol = 'tls';
|
|
597
623
|
|
|
598
624
|
await startStatsAnalyzer({expected: {receiveVideo: true}});
|
|
599
625
|
|
|
@@ -640,14 +666,131 @@ describe('plugin-meetings', () => {
|
|
|
640
666
|
);
|
|
641
667
|
});
|
|
642
668
|
|
|
643
|
-
it('emits the correct
|
|
644
|
-
|
|
669
|
+
it('emits the correct transmittedFrameRate/receivedFrameRate', async () => {
|
|
670
|
+
it('at the start of the stats analyzer', async () => {
|
|
671
|
+
await startStatsAnalyzer();
|
|
672
|
+
assert.strictEqual(mqeData.videoTransmit[0].streams[0].common.transmittedFrameRate, 0);
|
|
673
|
+
assert.strictEqual(mqeData.videoReceive[0].streams[0].common.receivedFrameRate, 0);
|
|
674
|
+
});
|
|
645
675
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
676
|
+
it('after frames are sent and received', async () => {
|
|
677
|
+
fakeStats.video.senders[0].report[0].framesSent += 300;
|
|
678
|
+
fakeStats.video.receivers[0].report[0].framesReceived += 300;
|
|
679
|
+
await progressTime(MQA_INTERVAL);
|
|
680
|
+
|
|
681
|
+
// 300 frames in 60 seconds = 5 frames per second
|
|
682
|
+
assert.strictEqual(mqeData.videoTransmit[0].streams[0].common.transmittedFrameRate, 5);
|
|
683
|
+
assert.strictEqual(mqeData.videoReceive[0].streams[0].common.receivedFrameRate, 5);
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('emits the correct rtpPackets', async () => {
|
|
688
|
+
it('at the start of the stats analyzer', async () => {
|
|
689
|
+
await startStatsAnalyzer();
|
|
690
|
+
assert.strictEqual(mqeData.audioTransmit[0].common.rtpPackets, 0);
|
|
691
|
+
assert.strictEqual(mqeData.audioTransmit[0].streams[0].common.rtpPackets, 0);
|
|
692
|
+
assert.strictEqual(mqeData.audioReceive[0].common.rtpPackets, 0);
|
|
693
|
+
assert.strictEqual(mqeData.audioReceive[0].streams[0].common.rtpPackets, 0);
|
|
694
|
+
assert.strictEqual(mqeData.videoTransmit[0].common.rtpPackets, 0);
|
|
695
|
+
assert.strictEqual(mqeData.videoTransmit[0].streams[0].common.rtpPackets, 0);
|
|
696
|
+
assert.strictEqual(mqeData.videoReceive[0].common.rtpPackets, 0);
|
|
697
|
+
assert.strictEqual(mqeData.videoReceive[0].streams[0].common.rtpPackets, 0);
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
it('after packets are sent', async () => {
|
|
701
|
+
fakeStats.audio.senders[0].report[0].packetsSent += 5;
|
|
702
|
+
fakeStats.video.senders[0].report[0].packetsSent += 5;
|
|
703
|
+
await progressTime(MQA_INTERVAL);
|
|
704
|
+
|
|
705
|
+
assert.strictEqual(mqeData.audioTransmit[0].common.rtpPackets, 5);
|
|
706
|
+
assert.strictEqual(mqeData.audioTransmit[0].streams[0].common.rtpPackets, 5);
|
|
707
|
+
assert.strictEqual(mqeData.videoTransmit[0].common.rtpPackets, 5);
|
|
708
|
+
assert.strictEqual(mqeData.videoTransmit[0].streams[0].common.rtpPackets, 5);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
it('after packets are received', async () => {
|
|
712
|
+
fakeStats.audio.senders[0].report[0].packetsSent += 10;
|
|
713
|
+
fakeStats.video.senders[0].report[0].packetsSent += 10;
|
|
714
|
+
fakeStats.audio.receivers[0].report[0].packetsReceived += 10;
|
|
715
|
+
fakeStats.video.receivers[0].report[0].packetsReceived += 10;
|
|
716
|
+
await progressTime(MQA_INTERVAL);
|
|
717
|
+
|
|
718
|
+
assert.strictEqual(mqeData.audioReceive[0].common.rtpPackets, 10);
|
|
719
|
+
assert.strictEqual(mqeData.audioReceive[0].streams[0].common.rtpPackets, 10);
|
|
720
|
+
assert.strictEqual(mqeData.videoReceive[0].common.rtpPackets, 10);
|
|
721
|
+
assert.strictEqual(mqeData.videoReceive[0].streams[0].common.rtpPackets, 10);
|
|
722
|
+
});
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
it('emits the correct fecPackets', async () => {
|
|
726
|
+
it('at the start of the stats analyzer', async () => {
|
|
727
|
+
await startStatsAnalyzer();
|
|
728
|
+
assert.strictEqual(mqeData.audioReceive[0].common.fecPackets, 0);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it('after FEC packets are received', async () => {
|
|
732
|
+
fakeStats.audio.receivers[0].report[0].fecPacketsReceived += 5;
|
|
733
|
+
await progressTime(MQA_INTERVAL);
|
|
734
|
+
|
|
735
|
+
assert.strictEqual(mqeData.audioReceive[0].common.fecPackets, 5);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
it('after FEC packets are received and some FEC packets are discarded', async () => {
|
|
739
|
+
fakeStats.audio.receivers[0].report[0].fecPacketsReceived += 15;
|
|
740
|
+
fakeStats.audio.receivers[0].report[0].fecPacketsDiscarded += 5;
|
|
741
|
+
await progressTime(MQA_INTERVAL);
|
|
742
|
+
|
|
743
|
+
assert.strictEqual(mqeData.audioReceive[0].common.fecPackets, 10);
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it('emits the correct mediaHopByHopLost/rtpHopByHopLost', async () => {
|
|
748
|
+
it('at the start of the stats analyzer', async () => {
|
|
749
|
+
await startStatsAnalyzer();
|
|
750
|
+
assert.strictEqual(mqeData.audioReceive[0].common.mediaHopByHopLost, 0);
|
|
751
|
+
assert.strictEqual(mqeData.audioReceive[0].common.rtpHopByHopLost, 0);
|
|
752
|
+
assert.strictEqual(mqeData.videoReceive[0].common.mediaHopByHopLost, 0);
|
|
753
|
+
assert.strictEqual(mqeData.videoReceive[0].common.rtpHopByHopLost, 0);
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
it('after packets are lost', async () => {
|
|
757
|
+
fakeStats.audio.receivers[0].report[0].packetsLost += 5;
|
|
758
|
+
fakeStats.video.receivers[0].report[0].packetsLost += 5;
|
|
759
|
+
await progressTime(MQA_INTERVAL);
|
|
760
|
+
|
|
761
|
+
assert.strictEqual(mqeData.audioReceive[0].common.mediaHopByHopLost, 5);
|
|
762
|
+
assert.strictEqual(mqeData.audioReceive[0].common.rtpHopByHopLost, 5);
|
|
763
|
+
assert.strictEqual(mqeData.videoReceive[0].common.mediaHopByHopLost, 5);
|
|
764
|
+
assert.strictEqual(mqeData.videoReceive[0].common.rtpHopByHopLost, 5);
|
|
765
|
+
});
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
it('emits the correct remoteLossRate', async () => {
|
|
769
|
+
it('at the start of the stats analyzer', async () => {
|
|
770
|
+
await startStatsAnalyzer();
|
|
771
|
+
assert.strictEqual(mqeData.audioTransmit[0].common.remoteLossRate, 0);
|
|
772
|
+
assert.strictEqual(mqeData.videoTransmit[0].common.remoteLossRate, 0);
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
it('after packets are sent', async () => {
|
|
776
|
+
fakeStats.audio.senders[0].report[0].packetsSent += 100;
|
|
777
|
+
fakeStats.video.senders[0].report[0].packetsSent += 100;
|
|
778
|
+
await progressTime(MQA_INTERVAL);
|
|
779
|
+
|
|
780
|
+
assert.strictEqual(mqeData.audioTransmit[0].common.remoteLossRate, 0);
|
|
781
|
+
assert.strictEqual(mqeData.videoTransmit[0].common.remoteLossRate, 0);
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
it('after packets are sent and some packets are lost', async () => {
|
|
785
|
+
fakeStats.audio.senders[0].report[0].packetsSent += 200;
|
|
786
|
+
fakeStats.audio.senders[0].report[1].packetsLost += 10;
|
|
787
|
+
fakeStats.video.senders[0].report[0].packetsSent += 200;
|
|
788
|
+
fakeStats.video.senders[0].report[1].packetsLost += 10;
|
|
789
|
+
await progressTime(MQA_INTERVAL);
|
|
790
|
+
|
|
791
|
+
assert.strictEqual(mqeData.audioTransmit[0].common.remoteLossRate, 5);
|
|
792
|
+
assert.strictEqual(mqeData.videoTransmit[0].common.remoteLossRate, 5);
|
|
793
|
+
});
|
|
651
794
|
});
|
|
652
795
|
|
|
653
796
|
it('has the correct localIpAddress set when the candidateType is host', async () => {
|
|
@@ -665,7 +808,11 @@ describe('plugin-meetings', () => {
|
|
|
665
808
|
|
|
666
809
|
await progressTime();
|
|
667
810
|
assert.strictEqual(statsAnalyzer.getLocalIpAddress(), '');
|
|
668
|
-
mergeProperties(fakeStats, {
|
|
811
|
+
mergeProperties(fakeStats, {
|
|
812
|
+
relayProtocol: 'test',
|
|
813
|
+
address: 'test2',
|
|
814
|
+
candidateType: 'prflx',
|
|
815
|
+
});
|
|
669
816
|
await progressTime();
|
|
670
817
|
assert.strictEqual(statsAnalyzer.getLocalIpAddress(), 'test2');
|
|
671
818
|
});
|
|
@@ -675,7 +822,11 @@ describe('plugin-meetings', () => {
|
|
|
675
822
|
|
|
676
823
|
await progressTime();
|
|
677
824
|
assert.strictEqual(statsAnalyzer.getLocalIpAddress(), '');
|
|
678
|
-
mergeProperties(fakeStats, {
|
|
825
|
+
mergeProperties(fakeStats, {
|
|
826
|
+
relatedAddress: 'relatedAddress',
|
|
827
|
+
address: 'test2',
|
|
828
|
+
candidateType: 'prflx',
|
|
829
|
+
});
|
|
679
830
|
await progressTime();
|
|
680
831
|
assert.strictEqual(statsAnalyzer.getLocalIpAddress(), 'relatedAddress');
|
|
681
832
|
});
|