@webex/plugin-meetings 3.8.0-next.7 → 3.8.0-next.70
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/common/errors/webex-errors.js +12 -2
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +17 -121
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +2 -0
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +52 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +28 -10
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +20 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +405 -418
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +14 -16
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +94 -6
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/brbState.js +6 -0
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +17 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +541 -302
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +0 -17
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +0 -2
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +30 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +13 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +359 -60
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +114 -1
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +14 -0
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +330 -353
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +23 -0
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +21 -0
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +15 -0
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +9 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reachability/clusterReachability.js +63 -27
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +112 -47
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachability.types.js +14 -0
- package/dist/reachability/reachability.types.js.map +1 -1
- package/dist/reachability/request.js +19 -3
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +2 -2
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/util.js +5 -5
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/turnDiscovery.js +45 -27
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/roap/types.js +17 -0
- package/dist/roap/types.js.map +1 -0
- package/dist/types/common/errors/webex-errors.d.ts +7 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +12 -85
- package/dist/types/controls-options-manager/enums.d.ts +3 -1
- package/dist/types/controls-options-manager/types.d.ts +7 -1
- package/dist/types/locus-info/index.d.ts +1 -0
- package/dist/types/locus-info/selfUtils.d.ts +247 -1
- package/dist/types/media/properties.d.ts +15 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +16 -0
- package/dist/types/meeting/index.d.ts +32 -1
- package/dist/types/meeting/muteState.d.ts +0 -1
- package/dist/types/meeting/request.d.ts +12 -1
- package/dist/types/meeting/request.type.d.ts +6 -0
- package/dist/types/meeting/util.d.ts +3 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +80 -0
- package/dist/types/meetings/index.d.ts +48 -0
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +159 -1
- package/dist/types/members/index.d.ts +8 -0
- package/dist/types/members/request.d.ts +19 -0
- package/dist/types/members/util.d.ts +13 -0
- package/dist/types/metrics/constants.d.ts +9 -0
- package/dist/types/reachability/clusterReachability.d.ts +15 -7
- package/dist/types/reachability/index.d.ts +10 -1
- package/dist/types/reachability/reachability.types.d.ts +5 -0
- package/dist/types/roap/index.d.ts +3 -2
- package/dist/types/roap/turnDiscovery.d.ts +5 -17
- package/dist/types/roap/types.d.ts +16 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +24 -23
- package/src/common/errors/webex-errors.ts +8 -1
- package/src/config.ts +2 -0
- package/src/constants.ts +19 -90
- package/src/controls-options-manager/enums.ts +2 -0
- package/src/controls-options-manager/types.ts +11 -1
- package/src/controls-options-manager/util.ts +62 -0
- package/src/locus-info/controlsUtils.ts +44 -14
- package/src/locus-info/index.ts +23 -1
- package/src/locus-info/selfUtils.ts +451 -447
- package/src/media/index.ts +20 -21
- package/src/media/properties.ts +96 -0
- package/src/meeting/brbState.ts +7 -0
- package/src/meeting/in-meeting-actions.ts +32 -0
- package/src/meeting/index.ts +346 -93
- package/src/meeting/locusMediaRequest.ts +0 -18
- package/src/meeting/muteState.ts +0 -2
- package/src/meeting/request.ts +36 -1
- package/src/meeting/request.type.ts +7 -0
- package/src/meeting/util.ts +11 -2
- package/src/meeting-info/meeting-info-v2.ts +247 -6
- package/src/meetings/index.ts +128 -1
- package/src/meetings/util.ts +18 -0
- package/src/member/index.ts +13 -2
- package/src/member/util.ts +351 -348
- package/src/members/index.ts +25 -0
- package/src/members/request.ts +26 -0
- package/src/members/util.ts +16 -0
- package/src/metrics/constants.ts +9 -0
- package/src/reachability/clusterReachability.ts +73 -26
- package/src/reachability/index.ts +70 -1
- package/src/reachability/reachability.types.ts +6 -0
- package/src/reachability/request.ts +7 -0
- package/src/reconnection-manager/index.ts +2 -2
- package/src/recording-controller/util.ts +17 -13
- package/src/roap/index.ts +3 -7
- package/src/roap/turnDiscovery.ts +34 -39
- package/src/roap/types.ts +23 -0
- package/test/unit/spec/controls-options-manager/util.js +120 -0
- package/test/unit/spec/locus-info/controlsUtils.js +103 -9
- package/test/unit/spec/locus-info/index.js +28 -0
- package/test/unit/spec/media/index.ts +98 -16
- package/test/unit/spec/media/properties.ts +130 -0
- package/test/unit/spec/meeting/brbState.ts +19 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +19 -4
- package/test/unit/spec/meeting/index.js +524 -35
- package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
- package/test/unit/spec/meeting/muteState.js +0 -2
- package/test/unit/spec/meeting/request.js +32 -1
- package/test/unit/spec/meeting/utils.js +119 -18
- package/test/unit/spec/meeting-info/meetinginfov2.js +443 -114
- package/test/unit/spec/meetings/index.js +133 -2
- package/test/unit/spec/member/index.js +7 -0
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/members/index.js +103 -26
- package/test/unit/spec/members/request.js +45 -22
- package/test/unit/spec/members/utils.js +33 -0
- package/test/unit/spec/reachability/clusterReachability.ts +88 -56
- package/test/unit/spec/reachability/index.ts +101 -0
- package/test/unit/spec/reachability/request.js +47 -2
- package/test/unit/spec/reconnection-manager/index.js +4 -4
- package/test/unit/spec/roap/turnDiscovery.ts +110 -28
@@ -9,7 +9,9 @@ import {
|
|
9
9
|
ResultEventData,
|
10
10
|
Events,
|
11
11
|
ClientMediaIpsUpdatedEventData,
|
12
|
+
NatTypeUpdatedEventData,
|
12
13
|
} from '@webex/plugin-meetings/src/reachability/clusterReachability'; // replace with actual path
|
14
|
+
import { NatType } from 'packages/@webex/plugin-meetings/dist/reachability/reachability.types';
|
13
15
|
|
14
16
|
describe('ClusterReachability', () => {
|
15
17
|
let previousRTCPeerConnection;
|
@@ -17,15 +19,17 @@ describe('ClusterReachability', () => {
|
|
17
19
|
let fakePeerConnection;
|
18
20
|
let gatherIceCandidatesSpy;
|
19
21
|
|
20
|
-
const emittedEvents: Record<Events, (ResultEventData | ClientMediaIpsUpdatedEventData)[]> = {
|
22
|
+
const emittedEvents: Record<Events, (ResultEventData | ClientMediaIpsUpdatedEventData | NatTypeUpdatedEventData)[]> = {
|
21
23
|
[Events.resultReady]: [],
|
22
24
|
[Events.clientMediaIpsUpdated]: [],
|
25
|
+
[Events.natTypeUpdated]: [],
|
23
26
|
};
|
24
27
|
const FAKE_OFFER = {type: 'offer', sdp: 'fake sdp'};
|
25
28
|
|
26
29
|
const resetEmittedEvents = () => {
|
27
30
|
emittedEvents[Events.resultReady].length = 0;
|
28
31
|
emittedEvents[Events.clientMediaIpsUpdated].length = 0;
|
32
|
+
emittedEvents[Events.natTypeUpdated].length = 0;
|
29
33
|
};
|
30
34
|
beforeEach(() => {
|
31
35
|
fakePeerConnection = {
|
@@ -56,6 +60,10 @@ describe('ClusterReachability', () => {
|
|
56
60
|
clusterReachability.on(Events.clientMediaIpsUpdated, (data: ClientMediaIpsUpdatedEventData) => {
|
57
61
|
emittedEvents[Events.clientMediaIpsUpdated].push(data);
|
58
62
|
});
|
63
|
+
|
64
|
+
clusterReachability.on(Events.natTypeUpdated, (data: NatTypeUpdatedEventData) => {
|
65
|
+
emittedEvents[Events.natTypeUpdated].push(data);
|
66
|
+
});
|
59
67
|
});
|
60
68
|
|
61
69
|
afterEach(() => {
|
@@ -166,59 +174,6 @@ describe('ClusterReachability', () => {
|
|
166
174
|
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated], []);
|
167
175
|
});
|
168
176
|
|
169
|
-
it('resolves and has correct result as soon as it finds that all udp, tcp and tls are reachable', async () => {
|
170
|
-
const promise = clusterReachability.start();
|
171
|
-
|
172
|
-
await clock.tickAsync(100);
|
173
|
-
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp'}});
|
174
|
-
|
175
|
-
// check the right events were emitted
|
176
|
-
assert.equal(emittedEvents[Events.resultReady].length, 1);
|
177
|
-
assert.deepEqual(emittedEvents[Events.resultReady][0], {
|
178
|
-
protocol: 'udp',
|
179
|
-
result: 'reachable',
|
180
|
-
latencyInMilliseconds: 100,
|
181
|
-
clientMediaIPs: ['somePublicIp'],
|
182
|
-
});
|
183
|
-
|
184
|
-
// clientMediaIpsUpdated shouldn't be emitted, because the IP is already passed in the resultReady event
|
185
|
-
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
186
|
-
|
187
|
-
await clock.tickAsync(100);
|
188
|
-
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
189
|
-
|
190
|
-
// check the right event was emitted
|
191
|
-
assert.equal(emittedEvents[Events.resultReady].length, 2);
|
192
|
-
assert.deepEqual(emittedEvents[Events.resultReady][1], {
|
193
|
-
protocol: 'tcp',
|
194
|
-
result: 'reachable',
|
195
|
-
latencyInMilliseconds: 200,
|
196
|
-
});
|
197
|
-
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
198
|
-
|
199
|
-
await clock.tickAsync(100);
|
200
|
-
fakePeerConnection.onicecandidate({
|
201
|
-
candidate: {type: 'relay', address: 'someTurnRelayIp', port: 443},
|
202
|
-
});
|
203
|
-
|
204
|
-
// check the right event was emitted
|
205
|
-
assert.equal(emittedEvents[Events.resultReady].length, 3);
|
206
|
-
assert.deepEqual(emittedEvents[Events.resultReady][2], {
|
207
|
-
protocol: 'xtls',
|
208
|
-
result: 'reachable',
|
209
|
-
latencyInMilliseconds: 300,
|
210
|
-
});
|
211
|
-
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
212
|
-
|
213
|
-
await promise;
|
214
|
-
|
215
|
-
assert.deepEqual(clusterReachability.getResult(), {
|
216
|
-
udp: {result: 'reachable', latencyInMilliseconds: 100, clientMediaIPs: ['somePublicIp']},
|
217
|
-
tcp: {result: 'reachable', latencyInMilliseconds: 200},
|
218
|
-
xtls: {result: 'reachable', latencyInMilliseconds: 300},
|
219
|
-
});
|
220
|
-
});
|
221
|
-
|
222
177
|
it('resolves and returns correct results when aborted before it gets any candidates', async () => {
|
223
178
|
const promise = clusterReachability.start();
|
224
179
|
|
@@ -267,7 +222,7 @@ describe('ClusterReachability', () => {
|
|
267
222
|
|
268
223
|
await testUtils.flushPromises();
|
269
224
|
|
270
|
-
fakePeerConnection.
|
225
|
+
fakePeerConnection.iceGatheringState = 'complete';
|
271
226
|
fakePeerConnection.onicegatheringstatechange();
|
272
227
|
await promise;
|
273
228
|
|
@@ -285,7 +240,7 @@ describe('ClusterReachability', () => {
|
|
285
240
|
await clock.tickAsync(30);
|
286
241
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
287
242
|
|
288
|
-
fakePeerConnection.
|
243
|
+
fakePeerConnection.iceGatheringState = 'complete';
|
289
244
|
fakePeerConnection.onicegatheringstatechange();
|
290
245
|
await promise;
|
291
246
|
|
@@ -428,6 +383,9 @@ describe('ClusterReachability', () => {
|
|
428
383
|
candidate: {type: 'relay', address: 'someTurnRelayIp', port: 443},
|
429
384
|
});
|
430
385
|
|
386
|
+
fakePeerConnection.iceGatheringState = 'complete';
|
387
|
+
fakePeerConnection.onicegatheringstatechange();
|
388
|
+
|
431
389
|
await promise;
|
432
390
|
|
433
391
|
assert.deepEqual(clusterReachability.getResult(), {
|
@@ -440,5 +398,79 @@ describe('ClusterReachability', () => {
|
|
440
398
|
xtls: {result: 'reachable', latencyInMilliseconds: 40},
|
441
399
|
});
|
442
400
|
});
|
401
|
+
|
402
|
+
it('determines correctly if symmetric-nat is detected', async () => {
|
403
|
+
const promise = clusterReachability.start();
|
404
|
+
|
405
|
+
// generate candidates with duplicate addresses
|
406
|
+
await clock.tickAsync(10);
|
407
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1', relatedPort: 3478, port: 1000}});
|
408
|
+
|
409
|
+
// check events emitted: there shouldn't be any natTypeUpdated emitted
|
410
|
+
assert.equal(emittedEvents[Events.natTypeUpdated].length, 0);
|
411
|
+
|
412
|
+
await clock.tickAsync(10);
|
413
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1', relatedPort: 3478, port: 2000}});
|
414
|
+
|
415
|
+
// should emit natTypeUpdated event
|
416
|
+
assert.equal(emittedEvents[Events.natTypeUpdated].length, 1);
|
417
|
+
assert.deepEqual(emittedEvents[Events.natTypeUpdated][0], {
|
418
|
+
natType: 'symmetric-nat',
|
419
|
+
});
|
420
|
+
|
421
|
+
// send also a relay candidate so that the reachability check finishes
|
422
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
423
|
+
fakePeerConnection.onicecandidate({
|
424
|
+
candidate: {type: 'relay', address: 'someTurnRelayIp', port: 443},
|
425
|
+
});
|
426
|
+
|
427
|
+
fakePeerConnection.iceGatheringState = 'complete';
|
428
|
+
fakePeerConnection.onicegatheringstatechange();
|
429
|
+
await clock.tickAsync(10);
|
430
|
+
|
431
|
+
await promise;
|
432
|
+
|
433
|
+
assert.deepEqual(clusterReachability.getResult(), {
|
434
|
+
udp: {
|
435
|
+
result: 'reachable',
|
436
|
+
latencyInMilliseconds: 10,
|
437
|
+
clientMediaIPs: ['somePublicIp1'],
|
438
|
+
},
|
439
|
+
tcp: {result: 'reachable', latencyInMilliseconds: 20},
|
440
|
+
xtls: {result: 'reachable', latencyInMilliseconds: 20},
|
441
|
+
});
|
442
|
+
});
|
443
|
+
|
444
|
+
it('should gather correctly reached subnets', async () => {
|
445
|
+
const promise = clusterReachability.start();
|
446
|
+
|
447
|
+
await clock.tickAsync(10);
|
448
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:1.2.3.4:5004'}});
|
449
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:4.3.2.1:5004'}});
|
450
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp'}});
|
451
|
+
|
452
|
+
clusterReachability.abort();
|
453
|
+
await promise;
|
454
|
+
|
455
|
+
assert.deepEqual(Array.from(clusterReachability.reachedSubnets), [
|
456
|
+
'1.2.3.4',
|
457
|
+
'4.3.2.1',
|
458
|
+
'someTurnRelayIp'
|
459
|
+
]);
|
460
|
+
});
|
461
|
+
|
462
|
+
it('should store only unique subnet address', async () => {
|
463
|
+
const promise = clusterReachability.start();
|
464
|
+
|
465
|
+
await clock.tickAsync(10);
|
466
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:1.2.3.4:5004'}});
|
467
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:1.2.3.4:9000'}});
|
468
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: '1.2.3.4'}});
|
469
|
+
|
470
|
+
clusterReachability.abort();
|
471
|
+
await promise;
|
472
|
+
|
473
|
+
assert.deepEqual(Array.from(clusterReachability.reachedSubnets), ['1.2.3.4']);
|
474
|
+
});
|
443
475
|
});
|
444
476
|
});
|
@@ -538,6 +538,14 @@ describe('gatherReachability', () => {
|
|
538
538
|
assert.equal(storedResultForJoinCookie, JSON.stringify(expectedJoinCookie));
|
539
539
|
};
|
540
540
|
|
541
|
+
it('rejects if reachability is disabled in config', async () => {
|
542
|
+
webex.config.meetings.enableReachabilityChecks = false;
|
543
|
+
|
544
|
+
const reachability = new Reachability(webex);
|
545
|
+
|
546
|
+
await assert.isRejected(reachability.gatherReachability('test'), 'enableReachabilityChecks is disabled in config');
|
547
|
+
});
|
548
|
+
|
541
549
|
[
|
542
550
|
// ========================================================================
|
543
551
|
{
|
@@ -1947,6 +1955,7 @@ describe('gatherReachability', () => {
|
|
1947
1955
|
receivedEvents[event] = receivedEvents[event] + 1 || 1;
|
1948
1956
|
});
|
1949
1957
|
};
|
1958
|
+
|
1950
1959
|
it('works as expected', async () => {
|
1951
1960
|
setListener('reachability:stopped');
|
1952
1961
|
setListener('reachability:done');
|
@@ -2008,6 +2017,59 @@ describe('gatherReachability', () => {
|
|
2008
2017
|
assert.equal(receivedEvents['reachability:done'], undefined);
|
2009
2018
|
assert.equal(receivedEvents['reachability:firstResultAvailable'], undefined);
|
2010
2019
|
});
|
2020
|
+
|
2021
|
+
it('does not fallback when no clusters were reached and min clusters were specified', async () => {
|
2022
|
+
setListener('reachability:stopped');
|
2023
|
+
setListener('reachability:done');
|
2024
|
+
setListener('reachability:firstResultAvailable');
|
2025
|
+
|
2026
|
+
const mockGetClustersResult = {
|
2027
|
+
discoveryOptions: {
|
2028
|
+
['early-call-min-clusters']: 1,
|
2029
|
+
},
|
2030
|
+
clusters: {
|
2031
|
+
clusterA: {
|
2032
|
+
udp: [],
|
2033
|
+
tcp: [],
|
2034
|
+
xtls: [],
|
2035
|
+
isVideoMesh: false,
|
2036
|
+
},
|
2037
|
+
clusterB: {
|
2038
|
+
udp: [],
|
2039
|
+
tcp: [],
|
2040
|
+
xtls: [],
|
2041
|
+
isVideoMesh: false,
|
2042
|
+
},
|
2043
|
+
},
|
2044
|
+
joinCookie: {id: 'id'},
|
2045
|
+
};
|
2046
|
+
|
2047
|
+
reachability.reachabilityRequest.getClusters = sinon.stub().returns(mockGetClustersResult);
|
2048
|
+
|
2049
|
+
const gatherReachabilityFallbackSpy = sinon.spy(reachability, 'gatherReachabilityFallback');
|
2050
|
+
|
2051
|
+
const resultPromise = reachability.gatherReachability('test');
|
2052
|
+
|
2053
|
+
await testUtils.flushPromises();
|
2054
|
+
|
2055
|
+
reachability.stopReachability();
|
2056
|
+
|
2057
|
+
await resultPromise;
|
2058
|
+
|
2059
|
+
// simulate a lot of time passing to check that all timers were stopped and nothing else happens
|
2060
|
+
clock.tick(99000);
|
2061
|
+
|
2062
|
+
assert.calledOnceWithExactly(mockClusterReachabilityInstances['clusterA'].abort);
|
2063
|
+
assert.calledOnceWithExactly(mockClusterReachabilityInstances['clusterB'].abort);
|
2064
|
+
|
2065
|
+
assert.calledOnceWithExactly(sendMetricSpy, true);
|
2066
|
+
|
2067
|
+
assert.equal(receivedEvents['reachability:stopped'], 1);
|
2068
|
+
assert.equal(receivedEvents['reachability:done'], undefined);
|
2069
|
+
assert.equal(receivedEvents['reachability:firstResultAvailable'], undefined);
|
2070
|
+
|
2071
|
+
assert.notCalled(gatherReachabilityFallbackSpy);
|
2072
|
+
});
|
2011
2073
|
});
|
2012
2074
|
});
|
2013
2075
|
|
@@ -2148,6 +2210,7 @@ describe('getReachabilityMetrics', () => {
|
|
2148
2210
|
reachability_vmn_tcp_failed: 0,
|
2149
2211
|
reachability_vmn_xtls_success: 0,
|
2150
2212
|
reachability_vmn_xtls_failed: 0,
|
2213
|
+
natType: 'unknown'
|
2151
2214
|
});
|
2152
2215
|
});
|
2153
2216
|
|
@@ -2215,6 +2278,7 @@ describe('getReachabilityMetrics', () => {
|
|
2215
2278
|
reachability_vmn_tcp_failed: 1,
|
2216
2279
|
reachability_vmn_xtls_success: 0,
|
2217
2280
|
reachability_vmn_xtls_failed: 0,
|
2281
|
+
natType: 'unknown'
|
2218
2282
|
}
|
2219
2283
|
);
|
2220
2284
|
});
|
@@ -2276,6 +2340,7 @@ describe('getReachabilityMetrics', () => {
|
|
2276
2340
|
reachability_vmn_tcp_failed: 0,
|
2277
2341
|
reachability_vmn_xtls_success: 0,
|
2278
2342
|
reachability_vmn_xtls_failed: 0,
|
2343
|
+
natType: 'unknown'
|
2279
2344
|
}
|
2280
2345
|
);
|
2281
2346
|
});
|
@@ -2337,6 +2402,7 @@ describe('getReachabilityMetrics', () => {
|
|
2337
2402
|
reachability_vmn_tcp_failed: 3,
|
2338
2403
|
reachability_vmn_xtls_success: 1,
|
2339
2404
|
reachability_vmn_xtls_failed: 1,
|
2405
|
+
natType: 'unknown'
|
2340
2406
|
}
|
2341
2407
|
);
|
2342
2408
|
});
|
@@ -2674,3 +2740,38 @@ describe('sendMetric', () => {
|
|
2674
2740
|
});
|
2675
2741
|
});
|
2676
2742
|
});
|
2743
|
+
|
2744
|
+
describe('isSubnetReachable', () => {
|
2745
|
+
let webex;
|
2746
|
+
let reachability;
|
2747
|
+
|
2748
|
+
beforeEach(() => {
|
2749
|
+
webex = new MockWebex();
|
2750
|
+
reachability = new TestReachability(webex);
|
2751
|
+
|
2752
|
+
reachability.setFakeClusterReachability({
|
2753
|
+
cluster1: {
|
2754
|
+
reachedSubnets: new Set(['1.2.3.4', '2.3.4.5']),
|
2755
|
+
},
|
2756
|
+
cluster2: {
|
2757
|
+
reachedSubnets: new Set(['3.4.5.6', '4.5.6.7']),
|
2758
|
+
},
|
2759
|
+
});
|
2760
|
+
});
|
2761
|
+
|
2762
|
+
afterEach(() => {
|
2763
|
+
sinon.restore();
|
2764
|
+
});
|
2765
|
+
|
2766
|
+
it('returns true if the subnet is reachable', () => {
|
2767
|
+
assert(reachability.isSubnetReachable('1.2.3.4'));
|
2768
|
+
});
|
2769
|
+
|
2770
|
+
it(`returns false if the subnet is unreachable`, () => {
|
2771
|
+
assert(!reachability.isSubnetReachable('11.2.3.4'));
|
2772
|
+
});
|
2773
|
+
|
2774
|
+
it('returns null if the subnet is not provided', () => {
|
2775
|
+
assert.isNull(reachability.isSubnetReachable(undefined));
|
2776
|
+
});
|
2777
|
+
});
|
@@ -12,6 +12,9 @@ describe('plugin-meetings/reachability', () => {
|
|
12
12
|
let reachabilityRequest;
|
13
13
|
let webex;
|
14
14
|
|
15
|
+
let appType;
|
16
|
+
let appVersion;
|
17
|
+
|
15
18
|
beforeEach(() => {
|
16
19
|
webex = new MockWebex({
|
17
20
|
children: {
|
@@ -20,6 +23,14 @@ describe('plugin-meetings/reachability', () => {
|
|
20
23
|
},
|
21
24
|
});
|
22
25
|
|
26
|
+
webex.config.support = {
|
27
|
+
'appType': 'NetworkChecker',
|
28
|
+
'appVersion': '43.3.0.1',
|
29
|
+
}
|
30
|
+
|
31
|
+
appType = webex?.config?.support?.appType;
|
32
|
+
appVersion = webex?.config?.support?.appVersion;
|
33
|
+
|
23
34
|
webex.meetings.clientRegion = {
|
24
35
|
countryCode: 'US',
|
25
36
|
regionCode: 'WEST-COAST',
|
@@ -56,7 +67,9 @@ describe('plugin-meetings/reachability', () => {
|
|
56
67
|
|
57
68
|
previousReport = {
|
58
69
|
id: 'fake previous report',
|
59
|
-
}
|
70
|
+
};
|
71
|
+
|
72
|
+
|
60
73
|
});
|
61
74
|
|
62
75
|
afterEach(() => {
|
@@ -79,6 +92,7 @@ describe('plugin-meetings/reachability', () => {
|
|
79
92
|
'report-version': 1,
|
80
93
|
'early-call-min-clusters': true,
|
81
94
|
},
|
95
|
+
'client-environment': { components: { [appType]: appVersion } },
|
82
96
|
'previous-report': previousReport,
|
83
97
|
trigger: 'startup',
|
84
98
|
},
|
@@ -105,6 +119,7 @@ describe('plugin-meetings/reachability', () => {
|
|
105
119
|
'report-version': 1,
|
106
120
|
'early-call-min-clusters': true,
|
107
121
|
},
|
122
|
+
'client-environment': { components: { [appType]: appVersion } },
|
108
123
|
'previous-report': previousReport,
|
109
124
|
trigger: 'early-call/no-min-reached',
|
110
125
|
},
|
@@ -114,5 +129,35 @@ describe('plugin-meetings/reachability', () => {
|
|
114
129
|
assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
|
115
130
|
assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency);
|
116
131
|
});
|
132
|
+
|
133
|
+
it('sends a POST request with the correct params when appVersion is undefined', async () => {
|
134
|
+
// Setting appType & appVersion to undefined
|
135
|
+
webex.config.support.appType = undefined;
|
136
|
+
webex.config.support.appVersion = undefined;
|
137
|
+
|
138
|
+
const res = await reachabilityRequest.getClusters('startup', IP_VERSION.only_ipv4, previousReport);
|
139
|
+
const requestParams = webex.request.getCall(0).args[0];
|
140
|
+
|
141
|
+
assert.deepEqual(requestParams, {
|
142
|
+
method: 'POST',
|
143
|
+
resource: `clusters`,
|
144
|
+
api: 'calliopeDiscovery',
|
145
|
+
shouldRefreshAccessToken: false,
|
146
|
+
timeout: 3000,
|
147
|
+
body: {
|
148
|
+
ipver: IP_VERSION.only_ipv4,
|
149
|
+
'supported-options': {
|
150
|
+
'report-version': 1,
|
151
|
+
'early-call-min-clusters': true,
|
152
|
+
},
|
153
|
+
'previous-report': previousReport,
|
154
|
+
trigger: 'startup',
|
155
|
+
},
|
156
|
+
});
|
157
|
+
|
158
|
+
assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true});
|
159
|
+
assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"});
|
160
|
+
assert.calledOnceWithExactly(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency, sinon.match.func, 'internal.get.cluster.time');
|
161
|
+
});
|
117
162
|
});
|
118
|
-
});
|
163
|
+
});
|
@@ -60,7 +60,7 @@ describe('plugin-meetings', () => {
|
|
60
60
|
roap: {
|
61
61
|
doTurnDiscovery: sinon.stub().resolves({
|
62
62
|
turnServerInfo: {
|
63
|
-
|
63
|
+
urls: ['fake_turn_url1', 'fake_turn_url2'],
|
64
64
|
username: 'fake_turn_username',
|
65
65
|
password: 'fake_turn_password',
|
66
66
|
},
|
@@ -137,7 +137,7 @@ describe('plugin-meetings', () => {
|
|
137
137
|
assert.calledOnce(fakeMediaConnection.reconnect);
|
138
138
|
assert.calledWith(fakeMediaConnection.reconnect, [
|
139
139
|
{
|
140
|
-
urls: '
|
140
|
+
urls: ['fake_turn_url1', 'fake_turn_url2'],
|
141
141
|
username: 'fake_turn_username',
|
142
142
|
credential: 'fake_turn_password',
|
143
143
|
},
|
@@ -152,12 +152,12 @@ describe('plugin-meetings', () => {
|
|
152
152
|
});
|
153
153
|
|
154
154
|
// this can happen when we land on a video mesh node
|
155
|
-
it('does not use TURN server if TURN
|
155
|
+
it('does not use TURN server if TURN urls is an empty array', async () => {
|
156
156
|
const rm = new ReconnectionManager(fakeMeeting);
|
157
157
|
|
158
158
|
fakeMeeting.roap.doTurnDiscovery.resolves({
|
159
159
|
turnServerInfo: {
|
160
|
-
|
160
|
+
urls: [],
|
161
161
|
username: 'whatever',
|
162
162
|
password: 'whatever',
|
163
163
|
},
|