@webex/plugin-meetings 2.60.1-next.13 → 2.60.1-next.15
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/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/mediaQualityMetrics/config.d.ts +103 -99
- package/dist/mediaQualityMetrics/config.js +133 -129
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/index.d.ts +0 -1
- package/dist/meeting/index.js +7 -15
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.d.ts +2 -0
- package/dist/meeting/request.js +4 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/voicea-meeting.d.ts +0 -4
- package/dist/meeting/voicea-meeting.js +26 -58
- package/dist/meeting/voicea-meeting.js.map +1 -1
- package/dist/meetings/index.js +19 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +1 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/metrics/constants.d.ts +2 -0
- package/dist/metrics/constants.js +3 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reachability/index.js +14 -20
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +63 -43
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/turnDiscovery.d.ts +18 -2
- package/dist/roap/turnDiscovery.js +163 -69
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/index.d.ts +7 -0
- package/dist/rtcMetrics/index.js +38 -1
- package/dist/rtcMetrics/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +135 -23
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.d.ts +28 -4
- package/dist/statsAnalyzer/mqaUtil.js +278 -148
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +21 -21
- package/src/mediaQualityMetrics/config.ts +107 -107
- package/src/meeting/index.ts +5 -18
- package/src/meeting/request.ts +6 -0
- package/src/meeting/voicea-meeting.ts +26 -65
- package/src/meetings/index.ts +22 -0
- package/src/meetings/util.ts +1 -1
- package/src/metrics/constants.ts +2 -0
- package/src/reachability/index.ts +0 -6
- package/src/reconnection-manager/index.ts +18 -7
- package/src/roap/turnDiscovery.ts +100 -24
- package/src/rtcMetrics/index.ts +43 -1
- package/src/statsAnalyzer/index.ts +158 -24
- package/src/statsAnalyzer/mqaUtil.ts +302 -154
- package/test/unit/spec/meeting/index.js +195 -4
- package/test/unit/spec/meeting/request.js +2 -0
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meetings/utils.js +35 -8
- package/test/unit/spec/reachability/index.ts +74 -0
- package/test/unit/spec/reconnection-manager/index.js +36 -1
- package/test/unit/spec/roap/turnDiscovery.ts +326 -76
- package/test/unit/spec/rtcMetrics/index.ts +32 -3
- package/test/unit/spec/stats-analyzer/index.js +439 -1
- package/test/utils/webex-test-users.js +12 -4
|
@@ -4,10 +4,15 @@ import {assert} from '@webex/test-helper-chai';
|
|
|
4
4
|
import sinon from 'sinon';
|
|
5
5
|
import RTC_METRICS from '../../../../src/rtcMetrics/constants';
|
|
6
6
|
|
|
7
|
-
const FAKE_METRICS_ITEM = {payload: ['fake-metrics']};
|
|
7
|
+
const FAKE_METRICS_ITEM = {payload: ['{"type":"string","value":"fake-metrics","id":""}']};
|
|
8
|
+
const FAILURE_METRICS_ITEM = {
|
|
9
|
+
name: "onconnectionstatechange",
|
|
10
|
+
payload: ['{"type":"string","value":"failed","id":""}'],
|
|
11
|
+
timestamp: 1707929986667
|
|
12
|
+
};
|
|
8
13
|
|
|
9
|
-
const STATS_WITH_IP = '{
|
|
10
|
-
const STATS_WITH_IP_RESULT = '{
|
|
14
|
+
const STATS_WITH_IP = '{"id":"RTCIceCandidate_/kQs0ZNU","type":"remote-candidate","transportId":"RTCTransport_0_1","isRemote":true,"ip":"11.22.111.255","address":"11.22.111.255","port":5004,"protocol":"udp","candidateType":"host","priority":2130706431}';
|
|
15
|
+
const STATS_WITH_IP_RESULT = '{"id":"RTCIceCandidate_/kQs0ZNU","type":"remote-candidate","transportId":"RTCTransport_0_1","isRemote":true,"ip":"11.22.111.240","address":"11.22.111.240","port":5004,"protocol":"udp","candidateType":"host","priority":2130706431}';
|
|
11
16
|
|
|
12
17
|
describe('RtcMetrics', () => {
|
|
13
18
|
let metrics: RtcMetrics;
|
|
@@ -82,6 +87,30 @@ describe('RtcMetrics', () => {
|
|
|
82
87
|
assert.callCount(webex.request, 1);
|
|
83
88
|
});
|
|
84
89
|
|
|
90
|
+
it('should clear out metrics on failure', () => {
|
|
91
|
+
assert.notCalled(webex.request);
|
|
92
|
+
|
|
93
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
94
|
+
|
|
95
|
+
assert.callCount(webex.request, 1);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should have the same connectionId on success', () => {
|
|
99
|
+
const originalId = metrics.connectionId;
|
|
100
|
+
|
|
101
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
102
|
+
|
|
103
|
+
assert.strictEqual(originalId, metrics.connectionId);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should have a new connectionId on failure', () => {
|
|
107
|
+
const originalId = metrics.connectionId;
|
|
108
|
+
|
|
109
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
110
|
+
|
|
111
|
+
assert.notEqual(originalId, metrics.connectionId);
|
|
112
|
+
});
|
|
113
|
+
|
|
85
114
|
it('should anonymize IP addresses', () => {
|
|
86
115
|
assert.strictEqual(metrics.anonymizeIp(STATS_WITH_IP), STATS_WITH_IP_RESULT);
|
|
87
116
|
});
|
|
@@ -244,6 +244,7 @@ describe('plugin-meetings', () => {
|
|
|
244
244
|
let statsAnalyzer;
|
|
245
245
|
let mqeData;
|
|
246
246
|
let loggerSpy;
|
|
247
|
+
let receiveSlot;
|
|
247
248
|
|
|
248
249
|
let receivedEventsData = {
|
|
249
250
|
local: {},
|
|
@@ -273,6 +274,7 @@ describe('plugin-meetings', () => {
|
|
|
273
274
|
|
|
274
275
|
beforeEach(() => {
|
|
275
276
|
clock = sinon.useFakeTimers();
|
|
277
|
+
receiveSlot = undefined;
|
|
276
278
|
|
|
277
279
|
resetReceivedEvents();
|
|
278
280
|
|
|
@@ -437,7 +439,7 @@ describe('plugin-meetings', () => {
|
|
|
437
439
|
|
|
438
440
|
networkQualityMonitor = new NetworkQualityMonitor(initialConfig);
|
|
439
441
|
|
|
440
|
-
statsAnalyzer = new StatsAnalyzer(initialConfig, () => (
|
|
442
|
+
statsAnalyzer = new StatsAnalyzer(initialConfig, () => (receiveSlot), networkQualityMonitor);
|
|
441
443
|
|
|
442
444
|
statsAnalyzer.on(EVENTS.LOCAL_MEDIA_STARTED, (data) => {
|
|
443
445
|
receivedEventsData.local.started = data;
|
|
@@ -912,6 +914,442 @@ describe('plugin-meetings', () => {
|
|
|
912
914
|
|
|
913
915
|
assert(loggerSpy.neverCalledWith('StatsAnalyzer:index#compareLastStatsResult --> No audio RTP packets received'));
|
|
914
916
|
});
|
|
917
|
+
|
|
918
|
+
it('logs a message when no packets are recieved for a receive slot with sourceState "live"', async () => {
|
|
919
|
+
receiveSlot = {
|
|
920
|
+
sourceState: 'live',
|
|
921
|
+
csi: 2,
|
|
922
|
+
id: "4",
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
await startStatsAnalyzer();
|
|
926
|
+
|
|
927
|
+
// don't increase the packets when time progresses.
|
|
928
|
+
await progressTime();
|
|
929
|
+
|
|
930
|
+
assert.calledWith(loggerSpy, 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot id: "4" and csi: 2. Total packets received on slot: ', 0);
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
["avatar", "invalid", "no source", "bandwidth limited", "policy violation"].forEach((sourceState) => {
|
|
934
|
+
it(`does not log a message when no packets are recieved for a receive slot with sourceState "${sourceState}"`, async () => {
|
|
935
|
+
receiveSlot = {
|
|
936
|
+
sourceState,
|
|
937
|
+
csi: 2,
|
|
938
|
+
id: "4",
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
await startStatsAnalyzer();
|
|
942
|
+
|
|
943
|
+
// don't increase the packets when time progresses.
|
|
944
|
+
await progressTime();
|
|
945
|
+
|
|
946
|
+
assert.neverCalledWith(loggerSpy, 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot id: "4" and csi: 2. Total packets received on slot: ', 0);
|
|
947
|
+
});
|
|
948
|
+
});
|
|
949
|
+
|
|
950
|
+
it(`does not log a message if receiveSlot is undefined`, async () => {
|
|
951
|
+
await startStatsAnalyzer();
|
|
952
|
+
|
|
953
|
+
// don't increase the packets when time progresses.
|
|
954
|
+
await progressTime();
|
|
955
|
+
|
|
956
|
+
assert.neverCalledWith(loggerSpy, 'StatsAnalyzer:index#processInboundRTPResult --> No packets received for receive slot "". Total packets received on slot: ', 0);
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
it('has the correct number of senders and receivers (2)', async () => {
|
|
960
|
+
await startStatsAnalyzer({expected: {receiveVideo: true}});
|
|
961
|
+
|
|
962
|
+
await progressTime();
|
|
963
|
+
|
|
964
|
+
assert.lengthOf(mqeData.audioTransmit, 2);
|
|
965
|
+
assert.lengthOf(mqeData.audioReceive, 2);
|
|
966
|
+
assert.lengthOf(mqeData.videoTransmit, 2);
|
|
967
|
+
assert.lengthOf(mqeData.videoReceive, 2);
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
it('has one stream per sender/reciever', async () => {
|
|
971
|
+
await startStatsAnalyzer({expected: {receiveVideo: true}});
|
|
972
|
+
|
|
973
|
+
await progressTime();
|
|
974
|
+
|
|
975
|
+
assert.deepEqual(
|
|
976
|
+
mqeData.audioTransmit[0].streams,
|
|
977
|
+
[
|
|
978
|
+
{
|
|
979
|
+
common: {
|
|
980
|
+
codec: 'opus',
|
|
981
|
+
csi: [],
|
|
982
|
+
requestedBitrate: 0,
|
|
983
|
+
requestedFrames: 0,
|
|
984
|
+
rtpPackets: 0,
|
|
985
|
+
ssci: 0,
|
|
986
|
+
transmittedBitrate: 0.13333333333333333,
|
|
987
|
+
transmittedFrameRate: 0
|
|
988
|
+
},
|
|
989
|
+
transmittedKeyFrames: 0,
|
|
990
|
+
requestedKeyFrames: 0
|
|
991
|
+
}
|
|
992
|
+
]
|
|
993
|
+
);
|
|
994
|
+
assert.deepEqual(
|
|
995
|
+
mqeData.audioTransmit[1].streams,
|
|
996
|
+
[
|
|
997
|
+
{
|
|
998
|
+
common: {
|
|
999
|
+
codec: 'opus',
|
|
1000
|
+
csi: [],
|
|
1001
|
+
requestedBitrate: 0,
|
|
1002
|
+
requestedFrames: 0,
|
|
1003
|
+
rtpPackets: 0,
|
|
1004
|
+
ssci: 0,
|
|
1005
|
+
transmittedBitrate: 0.13333333333333333,
|
|
1006
|
+
transmittedFrameRate: 0
|
|
1007
|
+
},
|
|
1008
|
+
transmittedKeyFrames: 0,
|
|
1009
|
+
requestedKeyFrames: 0
|
|
1010
|
+
}
|
|
1011
|
+
]
|
|
1012
|
+
);
|
|
1013
|
+
assert.deepEqual(
|
|
1014
|
+
mqeData.audioReceive[0].streams,
|
|
1015
|
+
[
|
|
1016
|
+
{
|
|
1017
|
+
common: {
|
|
1018
|
+
codec: 'opus',
|
|
1019
|
+
concealedFrames: 0,
|
|
1020
|
+
csi: [],
|
|
1021
|
+
maxConcealRunLength: 0,
|
|
1022
|
+
optimalBitrate: 0,
|
|
1023
|
+
optimalFrameRate: 0,
|
|
1024
|
+
receivedBitrate: 0.13333333333333333,
|
|
1025
|
+
receivedFrameRate: 0,
|
|
1026
|
+
renderedFrameRate: 0,
|
|
1027
|
+
requestedBitrate: 0,
|
|
1028
|
+
requestedFrameRate: 0,
|
|
1029
|
+
rtpEndToEndLost: 0,
|
|
1030
|
+
maxRtpJitter: 0,
|
|
1031
|
+
meanRtpJitter: 0,
|
|
1032
|
+
rtpPackets: 0,
|
|
1033
|
+
ssci: 0,
|
|
1034
|
+
rtpJitter: 0,
|
|
1035
|
+
framesDropped: 0,
|
|
1036
|
+
framesReceived: 0
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
]
|
|
1040
|
+
);
|
|
1041
|
+
assert.deepEqual(
|
|
1042
|
+
mqeData.audioReceive[1].streams,
|
|
1043
|
+
[
|
|
1044
|
+
{
|
|
1045
|
+
common: {
|
|
1046
|
+
codec: 'opus',
|
|
1047
|
+
concealedFrames: 0,
|
|
1048
|
+
csi: [],
|
|
1049
|
+
maxConcealRunLength: 0,
|
|
1050
|
+
optimalBitrate: 0,
|
|
1051
|
+
optimalFrameRate: 0,
|
|
1052
|
+
receivedBitrate: 0.13333333333333333,
|
|
1053
|
+
receivedFrameRate: 0,
|
|
1054
|
+
renderedFrameRate: 0,
|
|
1055
|
+
requestedBitrate: 0,
|
|
1056
|
+
requestedFrameRate: 0,
|
|
1057
|
+
rtpEndToEndLost: 0,
|
|
1058
|
+
maxRtpJitter: 0,
|
|
1059
|
+
meanRtpJitter: 0,
|
|
1060
|
+
rtpPackets: 0,
|
|
1061
|
+
ssci: 0,
|
|
1062
|
+
rtpJitter: 0,
|
|
1063
|
+
framesDropped: 0,
|
|
1064
|
+
framesReceived: 0
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
]
|
|
1068
|
+
);
|
|
1069
|
+
assert.deepEqual(
|
|
1070
|
+
mqeData.videoTransmit[0].streams,
|
|
1071
|
+
[
|
|
1072
|
+
{
|
|
1073
|
+
common: {
|
|
1074
|
+
codec: 'H264',
|
|
1075
|
+
csi: [],
|
|
1076
|
+
duplicateSsci: 0,
|
|
1077
|
+
requestedBitrate: 0,
|
|
1078
|
+
requestedFrames: 0,
|
|
1079
|
+
rtpPackets: 0,
|
|
1080
|
+
ssci: 0,
|
|
1081
|
+
transmittedBitrate: 0.13333333333333333,
|
|
1082
|
+
transmittedFrameRate: 0
|
|
1083
|
+
},
|
|
1084
|
+
h264CodecProfile: 'BP',
|
|
1085
|
+
isAvatar: false,
|
|
1086
|
+
isHardwareEncoded: false,
|
|
1087
|
+
localConfigurationChanges: 2,
|
|
1088
|
+
maxFrameQp: 0,
|
|
1089
|
+
maxNoiseLevel: 0,
|
|
1090
|
+
minRegionQp: 0,
|
|
1091
|
+
remoteConfigurationChanges: 0,
|
|
1092
|
+
requestedFrameSize: 0,
|
|
1093
|
+
requestedKeyFrames: 0,
|
|
1094
|
+
transmittedFrameSize: 0,
|
|
1095
|
+
transmittedHeight: 0,
|
|
1096
|
+
transmittedKeyFrames: 0,
|
|
1097
|
+
transmittedKeyFramesClient: 0,
|
|
1098
|
+
transmittedKeyFramesConfigurationChange: 0,
|
|
1099
|
+
transmittedKeyFramesFeedback: 0,
|
|
1100
|
+
transmittedKeyFramesLocalDrop: 0,
|
|
1101
|
+
transmittedKeyFramesOtherLayer: 0,
|
|
1102
|
+
transmittedKeyFramesPeriodic: 0,
|
|
1103
|
+
transmittedKeyFramesSceneChange: 0,
|
|
1104
|
+
transmittedKeyFramesStartup: 0,
|
|
1105
|
+
transmittedKeyFramesUnknown: 0,
|
|
1106
|
+
transmittedWidth: 0
|
|
1107
|
+
}
|
|
1108
|
+
]
|
|
1109
|
+
);
|
|
1110
|
+
assert.deepEqual(
|
|
1111
|
+
mqeData.videoTransmit[1].streams,
|
|
1112
|
+
[
|
|
1113
|
+
{
|
|
1114
|
+
common: {
|
|
1115
|
+
codec: 'H264',
|
|
1116
|
+
csi: [],
|
|
1117
|
+
duplicateSsci: 0,
|
|
1118
|
+
requestedBitrate: 0,
|
|
1119
|
+
requestedFrames: 0,
|
|
1120
|
+
rtpPackets: 0,
|
|
1121
|
+
ssci: 0,
|
|
1122
|
+
transmittedBitrate: 0.13333333333333333,
|
|
1123
|
+
transmittedFrameRate: 0
|
|
1124
|
+
},
|
|
1125
|
+
h264CodecProfile: 'BP',
|
|
1126
|
+
isAvatar: false,
|
|
1127
|
+
isHardwareEncoded: false,
|
|
1128
|
+
localConfigurationChanges: 2,
|
|
1129
|
+
maxFrameQp: 0,
|
|
1130
|
+
maxNoiseLevel: 0,
|
|
1131
|
+
minRegionQp: 0,
|
|
1132
|
+
remoteConfigurationChanges: 0,
|
|
1133
|
+
requestedFrameSize: 0,
|
|
1134
|
+
requestedKeyFrames: 0,
|
|
1135
|
+
transmittedFrameSize: 0,
|
|
1136
|
+
transmittedHeight: 0,
|
|
1137
|
+
transmittedKeyFrames: 0,
|
|
1138
|
+
transmittedKeyFramesClient: 0,
|
|
1139
|
+
transmittedKeyFramesConfigurationChange: 0,
|
|
1140
|
+
transmittedKeyFramesFeedback: 0,
|
|
1141
|
+
transmittedKeyFramesLocalDrop: 0,
|
|
1142
|
+
transmittedKeyFramesOtherLayer: 0,
|
|
1143
|
+
transmittedKeyFramesPeriodic: 0,
|
|
1144
|
+
transmittedKeyFramesSceneChange: 0,
|
|
1145
|
+
transmittedKeyFramesStartup: 0,
|
|
1146
|
+
transmittedKeyFramesUnknown: 0,
|
|
1147
|
+
transmittedWidth: 0
|
|
1148
|
+
}
|
|
1149
|
+
]
|
|
1150
|
+
);
|
|
1151
|
+
assert.deepEqual(
|
|
1152
|
+
mqeData.videoReceive[0].streams,
|
|
1153
|
+
[
|
|
1154
|
+
{
|
|
1155
|
+
common: {
|
|
1156
|
+
codec: 'H264',
|
|
1157
|
+
concealedFrames: 0,
|
|
1158
|
+
csi: [],
|
|
1159
|
+
maxConcealRunLength: 0,
|
|
1160
|
+
optimalBitrate: 0,
|
|
1161
|
+
optimalFrameRate: 0,
|
|
1162
|
+
receivedBitrate: 0.13333333333333333,
|
|
1163
|
+
receivedFrameRate: 0,
|
|
1164
|
+
renderedFrameRate: 0,
|
|
1165
|
+
requestedBitrate: 0,
|
|
1166
|
+
requestedFrameRate: 0,
|
|
1167
|
+
rtpEndToEndLost: 0,
|
|
1168
|
+
rtpJitter: 0,
|
|
1169
|
+
rtpPackets: 0,
|
|
1170
|
+
ssci: 0,
|
|
1171
|
+
framesDropped: 0
|
|
1172
|
+
},
|
|
1173
|
+
h264CodecProfile: 'BP',
|
|
1174
|
+
isActiveSpeaker: true,
|
|
1175
|
+
optimalFrameSize: 0,
|
|
1176
|
+
receivedFrameSize: 3600,
|
|
1177
|
+
receivedHeight: 720,
|
|
1178
|
+
receivedKeyFrames: 0,
|
|
1179
|
+
receivedKeyFramesForRequest: 0,
|
|
1180
|
+
receivedKeyFramesSourceChange: 0,
|
|
1181
|
+
receivedKeyFramesUnknown: 0,
|
|
1182
|
+
receivedWidth: 1280,
|
|
1183
|
+
requestedFrameSize: 0,
|
|
1184
|
+
requestedKeyFrames: 0
|
|
1185
|
+
}
|
|
1186
|
+
]
|
|
1187
|
+
);
|
|
1188
|
+
assert.deepEqual(
|
|
1189
|
+
mqeData.videoReceive[1].streams,
|
|
1190
|
+
[
|
|
1191
|
+
{
|
|
1192
|
+
common: {
|
|
1193
|
+
codec: 'H264',
|
|
1194
|
+
concealedFrames: 0,
|
|
1195
|
+
csi: [],
|
|
1196
|
+
maxConcealRunLength: 0,
|
|
1197
|
+
optimalBitrate: 0,
|
|
1198
|
+
optimalFrameRate: 0,
|
|
1199
|
+
receivedBitrate: 0.13333333333333333,
|
|
1200
|
+
receivedFrameRate: 0,
|
|
1201
|
+
renderedFrameRate: 0,
|
|
1202
|
+
requestedBitrate: 0,
|
|
1203
|
+
requestedFrameRate: 0,
|
|
1204
|
+
rtpEndToEndLost: 0,
|
|
1205
|
+
rtpJitter: 0,
|
|
1206
|
+
rtpPackets: 0,
|
|
1207
|
+
ssci: 0,
|
|
1208
|
+
framesDropped: 0
|
|
1209
|
+
},
|
|
1210
|
+
h264CodecProfile: 'BP',
|
|
1211
|
+
isActiveSpeaker: true,
|
|
1212
|
+
optimalFrameSize: 0,
|
|
1213
|
+
receivedFrameSize: 3600,
|
|
1214
|
+
receivedHeight: 720,
|
|
1215
|
+
receivedKeyFrames: 0,
|
|
1216
|
+
receivedKeyFramesForRequest: 0,
|
|
1217
|
+
receivedKeyFramesSourceChange: 0,
|
|
1218
|
+
receivedKeyFramesUnknown: 0,
|
|
1219
|
+
receivedWidth: 1280,
|
|
1220
|
+
requestedFrameSize: 0,
|
|
1221
|
+
requestedKeyFrames: 0
|
|
1222
|
+
}
|
|
1223
|
+
]
|
|
1224
|
+
);
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1227
|
+
it('has three streams for video receivers when three exist', async () => {
|
|
1228
|
+
pc.getTransceiverStats = sinon.stub().resolves({
|
|
1229
|
+
audio: {
|
|
1230
|
+
senders: [fakeStats.audio.senders[0]],
|
|
1231
|
+
receivers: [fakeStats.audio.receivers[0]],
|
|
1232
|
+
},
|
|
1233
|
+
video: {
|
|
1234
|
+
senders: [fakeStats.video.senders[0]],
|
|
1235
|
+
receivers: [fakeStats.video.receivers[0], fakeStats.video.receivers[0], fakeStats.video.receivers[0]],
|
|
1236
|
+
},
|
|
1237
|
+
screenShareAudio: {
|
|
1238
|
+
senders: [fakeStats.audio.senders[0]],
|
|
1239
|
+
receivers: [fakeStats.audio.receivers[0]],
|
|
1240
|
+
},
|
|
1241
|
+
screenShareVideo: {
|
|
1242
|
+
senders: [fakeStats.video.senders[0]],
|
|
1243
|
+
receivers: [fakeStats.video.receivers[0]],
|
|
1244
|
+
},
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
await startStatsAnalyzer({expected: {receiveVideo: true}});
|
|
1248
|
+
|
|
1249
|
+
await progressTime();
|
|
1250
|
+
|
|
1251
|
+
assert.deepEqual(
|
|
1252
|
+
mqeData.videoReceive[0].streams,
|
|
1253
|
+
[
|
|
1254
|
+
{
|
|
1255
|
+
common: {
|
|
1256
|
+
codec: 'H264',
|
|
1257
|
+
concealedFrames: 0,
|
|
1258
|
+
csi: [],
|
|
1259
|
+
maxConcealRunLength: 0,
|
|
1260
|
+
optimalBitrate: 0,
|
|
1261
|
+
optimalFrameRate: 0,
|
|
1262
|
+
receivedBitrate: 0.13333333333333333,
|
|
1263
|
+
receivedFrameRate: 0,
|
|
1264
|
+
renderedFrameRate: 0,
|
|
1265
|
+
requestedBitrate: 0,
|
|
1266
|
+
requestedFrameRate: 0,
|
|
1267
|
+
rtpEndToEndLost: 0,
|
|
1268
|
+
rtpJitter: 0,
|
|
1269
|
+
rtpPackets: 0,
|
|
1270
|
+
ssci: 0,
|
|
1271
|
+
framesDropped: 0
|
|
1272
|
+
},
|
|
1273
|
+
h264CodecProfile: 'BP',
|
|
1274
|
+
isActiveSpeaker: true,
|
|
1275
|
+
optimalFrameSize: 0,
|
|
1276
|
+
receivedFrameSize: 3600,
|
|
1277
|
+
receivedHeight: 720,
|
|
1278
|
+
receivedKeyFrames: 0,
|
|
1279
|
+
receivedKeyFramesForRequest: 0,
|
|
1280
|
+
receivedKeyFramesSourceChange: 0,
|
|
1281
|
+
receivedKeyFramesUnknown: 0,
|
|
1282
|
+
receivedWidth: 1280,
|
|
1283
|
+
requestedFrameSize: 0,
|
|
1284
|
+
requestedKeyFrames: 0
|
|
1285
|
+
},
|
|
1286
|
+
{
|
|
1287
|
+
common: {
|
|
1288
|
+
codec: 'H264',
|
|
1289
|
+
concealedFrames: 0,
|
|
1290
|
+
csi: [],
|
|
1291
|
+
maxConcealRunLength: 0,
|
|
1292
|
+
optimalBitrate: 0,
|
|
1293
|
+
optimalFrameRate: 0,
|
|
1294
|
+
receivedBitrate: 0.13333333333333333,
|
|
1295
|
+
receivedFrameRate: 0,
|
|
1296
|
+
renderedFrameRate: 0,
|
|
1297
|
+
requestedBitrate: 0,
|
|
1298
|
+
requestedFrameRate: 0,
|
|
1299
|
+
rtpEndToEndLost: 0,
|
|
1300
|
+
rtpJitter: 0,
|
|
1301
|
+
rtpPackets: 0,
|
|
1302
|
+
ssci: 0,
|
|
1303
|
+
framesDropped: 0
|
|
1304
|
+
},
|
|
1305
|
+
h264CodecProfile: 'BP',
|
|
1306
|
+
isActiveSpeaker: true,
|
|
1307
|
+
optimalFrameSize: 0,
|
|
1308
|
+
receivedFrameSize: 3600,
|
|
1309
|
+
receivedHeight: 720,
|
|
1310
|
+
receivedKeyFrames: 0,
|
|
1311
|
+
receivedKeyFramesForRequest: 0,
|
|
1312
|
+
receivedKeyFramesSourceChange: 0,
|
|
1313
|
+
receivedKeyFramesUnknown: 0,
|
|
1314
|
+
receivedWidth: 1280,
|
|
1315
|
+
requestedFrameSize: 0,
|
|
1316
|
+
requestedKeyFrames: 0
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
common: {
|
|
1320
|
+
codec: 'H264',
|
|
1321
|
+
concealedFrames: 0,
|
|
1322
|
+
csi: [],
|
|
1323
|
+
maxConcealRunLength: 0,
|
|
1324
|
+
optimalBitrate: 0,
|
|
1325
|
+
optimalFrameRate: 0,
|
|
1326
|
+
receivedBitrate: 0.13333333333333333,
|
|
1327
|
+
receivedFrameRate: 0,
|
|
1328
|
+
renderedFrameRate: 0,
|
|
1329
|
+
requestedBitrate: 0,
|
|
1330
|
+
requestedFrameRate: 0,
|
|
1331
|
+
rtpEndToEndLost: 0,
|
|
1332
|
+
rtpJitter: 0,
|
|
1333
|
+
rtpPackets: 0,
|
|
1334
|
+
ssci: 0,
|
|
1335
|
+
framesDropped: 0
|
|
1336
|
+
},
|
|
1337
|
+
h264CodecProfile: 'BP',
|
|
1338
|
+
isActiveSpeaker: true,
|
|
1339
|
+
optimalFrameSize: 0,
|
|
1340
|
+
receivedFrameSize: 3600,
|
|
1341
|
+
receivedHeight: 720,
|
|
1342
|
+
receivedKeyFrames: 0,
|
|
1343
|
+
receivedKeyFramesForRequest: 0,
|
|
1344
|
+
receivedKeyFramesSourceChange: 0,
|
|
1345
|
+
receivedKeyFramesUnknown: 0,
|
|
1346
|
+
receivedWidth: 1280,
|
|
1347
|
+
requestedFrameSize: 0,
|
|
1348
|
+
requestedKeyFrames: 0
|
|
1349
|
+
}
|
|
1350
|
+
]
|
|
1351
|
+
);
|
|
1352
|
+
});
|
|
915
1353
|
});
|
|
916
1354
|
});
|
|
917
1355
|
});
|
|
@@ -17,7 +17,7 @@ require('@webex/plugin-people');
|
|
|
17
17
|
require('@webex/plugin-rooms');
|
|
18
18
|
require('@webex/plugin-meetings');
|
|
19
19
|
|
|
20
|
-
const generateTestUsers = (options = {}) => {
|
|
20
|
+
const generateTestUsers = async (options = {}) => {
|
|
21
21
|
options.config = options.config || {};
|
|
22
22
|
options.config.orgId = options.config.orgId || process.env.WEBEX_CONVERGED_ORG_ID;
|
|
23
23
|
|
|
@@ -30,7 +30,8 @@ const generateTestUsers = (options = {}) => {
|
|
|
30
30
|
// Pause for 5 seconds for CI
|
|
31
31
|
await new Promise((done) => setTimeout(done, 5000));
|
|
32
32
|
|
|
33
|
-
const
|
|
33
|
+
const webexRegisterPromises = [];
|
|
34
|
+
const userWebexMeetings = [];
|
|
34
35
|
|
|
35
36
|
userSet.forEach((user) => {
|
|
36
37
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -44,12 +45,19 @@ const generateTestUsers = (options = {}) => {
|
|
|
44
45
|
},
|
|
45
46
|
});
|
|
46
47
|
|
|
48
|
+
webexRegisterPromises.push(new Promise((resolve) => {
|
|
49
|
+
user.webex.on('ready', resolve);
|
|
50
|
+
}));
|
|
51
|
+
|
|
47
52
|
user.webex.internal.support.submitLogs = sinon.stub().returns(Promise.resolve());
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
userWebexMeetings.push(user.webex.meetings);
|
|
50
55
|
});
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
// wait for webex to be ready before registering meetings
|
|
58
|
+
return Promise.all(webexRegisterPromises).then(() => {
|
|
59
|
+
return Promise.all(userWebexMeetings.map(m => m.register())).then(() => userSet);
|
|
60
|
+
})
|
|
53
61
|
})
|
|
54
62
|
.catch((error) => {
|
|
55
63
|
console.error('#generateTestUsers=>ERROR', error);
|