@webex/plugin-meetings 3.10.0-next.3 → 3.10.0-next.30
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/annotation/annotation.types.js.map +1 -1
- package/dist/annotation/constants.js.map +1 -1
- package/dist/annotation/index.js +19 -22
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +6 -6
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/collection.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +9 -11
- package/dist/breakouts/edit-lock-error.js.map +1 -1
- package/dist/breakouts/events.js.map +1 -1
- package/dist/breakouts/index.js +126 -127
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +6 -8
- package/dist/breakouts/request.js.map +1 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +1 -2
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +9 -11
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +10 -12
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-forbidden-error.js +10 -12
- package/dist/common/errors/join-forbidden-error.js.map +1 -1
- package/dist/common/errors/join-meeting.js +10 -12
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/join-webinar-error.js +9 -11
- package/dist/common/errors/join-webinar-error.js.map +1 -1
- package/dist/common/errors/media.js +9 -11
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/multistream-not-supported-error.js +9 -11
- package/dist/common/errors/multistream-not-supported-error.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +9 -11
- package/dist/common/errors/no-meeting-info.js.map +1 -1
- package/dist/common/errors/parameter.js +11 -14
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +9 -11
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +9 -11
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.js +32 -38
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -1
- package/dist/common/errors/reconnection-not-started.js +5 -6
- package/dist/common/errors/reconnection-not-started.js.map +1 -1
- package/dist/common/errors/reconnection.js +9 -11
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +9 -11
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js +20 -29
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +9 -12
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +9 -10
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +9 -10
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +17 -17
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +1 -2
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/constants.js +11 -8
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +1 -2
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +1 -2
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/hashTree/constants.js +20 -0
- package/dist/hashTree/constants.js.map +1 -0
- package/dist/hashTree/hashTree.js +515 -0
- package/dist/hashTree/hashTree.js.map +1 -0
- package/dist/hashTree/hashTreeParser.js +1250 -0
- package/dist/hashTree/hashTreeParser.js.map +1 -0
- package/dist/hashTree/types.js +23 -0
- package/dist/hashTree/types.js.map +1 -0
- package/dist/hashTree/utils.js +59 -0
- package/dist/hashTree/utils.js.map +1 -0
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRetry.js +6 -8
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +26 -12
- package/dist/interceptors/locusRouteToken.js.map +1 -1
- package/dist/interpretation/collection.js.map +1 -1
- package/dist/interpretation/index.js +1 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/interpretation/siLanguage.js.map +1 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +609 -177
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +3 -4
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js +7 -0
- package/dist/locus-info/types.js.map +1 -0
- package/dist/media/MediaConnectionAwaiter.js +1 -2
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/index.js +0 -2
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +15 -17
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js.map +1 -1
- package/dist/meeting/brbState.js +8 -9
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +10 -13
- package/dist/meeting/connectionStateHandler.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1576 -1533
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +13 -17
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +11 -12
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +101 -104
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/type.js.map +1 -1
- package/dist/meeting/util.js +24 -23
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +3 -3
- package/dist/meeting/voicea-meeting.js.map +1 -1
- package/dist/meeting-info/collection.js +7 -10
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +1 -2
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +135 -146
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +36 -37
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +30 -31
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +6 -8
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +200 -148
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/request.js +6 -8
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +36 -30
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +1 -2
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +6 -3
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +1 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +18 -21
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +8 -11
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js.map +1 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +3 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +3 -4
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -2
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +34 -45
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +8 -9
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +12 -15
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +1 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +122 -123
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +29 -30
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/personal-meeting-room/index.js +16 -19
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +7 -10
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/clusterReachability.js +188 -352
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +206 -206
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachability.types.js +14 -1
- package/dist/reachability/reachability.types.js.map +1 -1
- package/dist/reachability/reachabilityPeerConnection.js +445 -0
- package/dist/reachability/reachabilityPeerConnection.js.map +1 -0
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js.map +1 -1
- package/dist/reactions/constants.js.map +1 -1
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +178 -176
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.js +1 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +12 -15
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +24 -26
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +75 -76
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/roap/types.js.map +1 -1
- package/dist/transcription/index.js +4 -5
- package/dist/transcription/index.js.map +1 -1
- package/dist/types/config.d.ts +1 -0
- package/dist/types/constants.d.ts +26 -21
- package/dist/types/hashTree/constants.d.ts +8 -0
- package/dist/types/hashTree/hashTree.d.ts +129 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +250 -0
- package/dist/types/hashTree/types.d.ts +33 -0
- package/dist/types/hashTree/utils.d.ts +16 -0
- package/dist/types/interceptors/locusRouteToken.d.ts +1 -0
- package/dist/types/locus-info/index.d.ts +98 -80
- package/dist/types/locus-info/types.d.ts +54 -0
- package/dist/types/meeting/index.d.ts +22 -9
- package/dist/types/meetings/index.d.ts +9 -2
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/reachability/clusterReachability.d.ts +33 -84
- package/dist/types/reachability/reachability.types.d.ts +12 -1
- package/dist/types/reachability/reachabilityPeerConnection.d.ts +111 -0
- package/dist/webinar/collection.js +1 -2
- package/dist/webinar/collection.js.map +1 -1
- package/dist/webinar/index.js +148 -158
- package/dist/webinar/index.js.map +1 -1
- package/package.json +23 -22
- package/src/config.ts +1 -0
- package/src/constants.ts +13 -1
- package/src/hashTree/constants.ts +9 -0
- package/src/hashTree/hashTree.ts +463 -0
- package/src/hashTree/hashTreeParser.ts +1143 -0
- package/src/hashTree/types.ts +39 -0
- package/src/hashTree/utils.ts +53 -0
- package/src/interceptors/locusRouteToken.ts +16 -4
- package/src/locus-info/index.ts +625 -164
- package/src/locus-info/types.ts +53 -0
- package/src/meeting/index.ts +78 -27
- package/src/meeting/util.ts +1 -0
- package/src/meetings/index.ts +119 -59
- package/src/meetings/util.ts +10 -9
- package/src/metrics/constants.ts +2 -0
- package/src/reachability/clusterReachability.ts +159 -330
- package/src/reachability/index.ts +6 -1
- package/src/reachability/reachability.types.ts +15 -1
- package/src/reachability/reachabilityPeerConnection.ts +418 -0
- package/test/unit/spec/hashTree/hashTree.ts +655 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1524 -0
- package/test/unit/spec/hashTree/utils.ts +140 -0
- package/test/unit/spec/interceptors/locusRouteToken.ts +27 -0
- package/test/unit/spec/locus-info/index.js +851 -16
- package/test/unit/spec/meeting/index.js +120 -20
- package/test/unit/spec/meeting/utils.js +77 -0
- package/test/unit/spec/meetings/index.js +263 -27
- package/test/unit/spec/meetings/utils.js +51 -1
- package/test/unit/spec/reachability/clusterReachability.ts +404 -137
- package/test/unit/spec/reachability/index.ts +3 -3
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
|
-
import MockWebex from '@webex/test-helper-mock-webex';
|
|
3
2
|
import sinon from 'sinon';
|
|
4
3
|
import testUtils from '../../../utils/testUtils';
|
|
5
4
|
|
|
6
|
-
// packages/@webex/plugin-meetings/test/unit/spec/reachability/clusterReachability.ts
|
|
7
5
|
import {
|
|
8
6
|
ClusterReachability,
|
|
9
7
|
ResultEventData,
|
|
10
8
|
Events,
|
|
11
9
|
ClientMediaIpsUpdatedEventData,
|
|
12
10
|
NatTypeUpdatedEventData,
|
|
13
|
-
} from '@webex/plugin-meetings/src/reachability/clusterReachability';
|
|
14
|
-
import {
|
|
11
|
+
} from '@webex/plugin-meetings/src/reachability/clusterReachability';
|
|
12
|
+
import {ReachabilityPeerConnection} from '@webex/plugin-meetings/src/reachability/reachabilityPeerConnection';
|
|
13
|
+
import {ReachabilityPeerConnectionEvents} from '@webex/plugin-meetings/src/reachability/reachability.types';
|
|
15
14
|
|
|
16
15
|
describe('ClusterReachability', () => {
|
|
17
16
|
let previousRTCPeerConnection;
|
|
@@ -49,7 +48,7 @@ describe('ClusterReachability', () => {
|
|
|
49
48
|
xtls: ['stun:xtls1.webex.com', 'stun:xtls2.webex.com:443'],
|
|
50
49
|
});
|
|
51
50
|
|
|
52
|
-
gatherIceCandidatesSpy = sinon.spy(clusterReachability, 'gatherIceCandidates');
|
|
51
|
+
gatherIceCandidatesSpy = sinon.spy(clusterReachability.reachabilityPeerConnection as any, 'gatherIceCandidates');
|
|
53
52
|
|
|
54
53
|
resetEmittedEvents();
|
|
55
54
|
|
|
@@ -70,75 +69,341 @@ describe('ClusterReachability', () => {
|
|
|
70
69
|
global.RTCPeerConnection = previousRTCPeerConnection;
|
|
71
70
|
});
|
|
72
71
|
|
|
73
|
-
it('should create an instance correctly', () => {
|
|
72
|
+
it('should create an instance correctly with provided cluster info', () => {
|
|
74
73
|
assert.instanceOf(clusterReachability, ClusterReachability);
|
|
75
74
|
assert.equal(clusterReachability.name, 'testName');
|
|
76
75
|
assert.equal(clusterReachability.isVideoMesh, false);
|
|
77
|
-
assert.
|
|
78
|
-
assert.equal(clusterReachability.numTcpUrls, 2);
|
|
76
|
+
assert.instanceOf(clusterReachability.reachabilityPeerConnection, ReachabilityPeerConnection);
|
|
79
77
|
});
|
|
80
78
|
|
|
81
|
-
it('should
|
|
82
|
-
assert.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
it('should initialize reachedSubnets as empty set', () => {
|
|
80
|
+
assert.instanceOf(clusterReachability.reachedSubnets, Set);
|
|
81
|
+
assert.equal(clusterReachability.reachedSubnets.size, 0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('returns correct results before start() is called', () => {
|
|
85
|
+
assert.deepEqual(clusterReachability.getResult(), {
|
|
86
|
+
udp: {result: 'untested'},
|
|
87
|
+
tcp: {result: 'untested'},
|
|
88
|
+
xtls: {result: 'untested'},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// verify that no events were emitted
|
|
92
|
+
assert.deepEqual(emittedEvents[Events.resultReady], []);
|
|
93
|
+
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated], []);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should create separate peer connections when enablePerUdpUrlReachability is true', () => {
|
|
97
|
+
const perUdpClusterReachability = new ClusterReachability(
|
|
98
|
+
'testName',
|
|
99
|
+
{
|
|
100
|
+
isVideoMesh: false,
|
|
101
|
+
udp: ['stun:udp1', 'stun:udp2'],
|
|
102
|
+
tcp: ['stun:tcp1.webex.com'],
|
|
103
|
+
xtls: ['stun:xtls1.webex.com'],
|
|
104
|
+
},
|
|
105
|
+
true
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
assert.equal((perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp.length, 2);
|
|
109
|
+
assert.instanceOf((perUdpClusterReachability as any).reachabilityPeerConnection, ReachabilityPeerConnection);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('#event relaying', () => {
|
|
113
|
+
let clock;
|
|
114
|
+
|
|
115
|
+
beforeEach(() => {
|
|
116
|
+
clock = sinon.useFakeTimers();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
afterEach(() => {
|
|
120
|
+
clock.restore();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('relays resultReady event from ReachabilityPeerConnection', async () => {
|
|
124
|
+
const promise = clusterReachability.start();
|
|
125
|
+
|
|
126
|
+
await testUtils.flushPromises();
|
|
127
|
+
|
|
128
|
+
// Simulate RPC emitting resultReady
|
|
129
|
+
await clock.tickAsync(50);
|
|
130
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
131
|
+
|
|
132
|
+
// ClusterReachability should relay the event
|
|
133
|
+
assert.equal(emittedEvents[Events.resultReady].length, 1);
|
|
134
|
+
assert.deepEqual(emittedEvents[Events.resultReady][0], {
|
|
135
|
+
protocol: 'udp',
|
|
136
|
+
result: 'reachable',
|
|
137
|
+
latencyInMilliseconds: 50,
|
|
138
|
+
clientMediaIPs: ['somePublicIp1'],
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
clusterReachability.abort();
|
|
142
|
+
await promise;
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('relays clientMediaIpsUpdated event from ReachabilityPeerConnection', async () => {
|
|
146
|
+
const promise = clusterReachability.start();
|
|
147
|
+
|
|
148
|
+
await clock.tickAsync(10);
|
|
149
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
150
|
+
|
|
151
|
+
// First IP found - only resultReady emitted
|
|
152
|
+
assert.equal(emittedEvents[Events.resultReady].length, 1);
|
|
153
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 0);
|
|
154
|
+
resetEmittedEvents();
|
|
155
|
+
|
|
156
|
+
// New IP found - should emit clientMediaIpsUpdated
|
|
157
|
+
await clock.tickAsync(10);
|
|
158
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
|
|
159
|
+
|
|
160
|
+
assert.equal(emittedEvents[Events.resultReady].length, 0);
|
|
161
|
+
assert.equal(emittedEvents[Events.clientMediaIpsUpdated].length, 1);
|
|
162
|
+
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated][0], {
|
|
163
|
+
protocol: 'udp',
|
|
164
|
+
clientMediaIPs: ['somePublicIp1', 'somePublicIp2'],
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
clusterReachability.abort();
|
|
168
|
+
await promise;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('relays natTypeUpdated event from ReachabilityPeerConnection', async () => {
|
|
172
|
+
const promise = clusterReachability.start();
|
|
173
|
+
|
|
174
|
+
await clock.tickAsync(10);
|
|
175
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1', port: 1000, relatedPort: 3478}});
|
|
176
|
+
|
|
177
|
+
// No NAT detection yet (only 1 candidate)
|
|
178
|
+
assert.equal(emittedEvents[Events.natTypeUpdated].length, 0);
|
|
179
|
+
|
|
180
|
+
// Second candidate with same address but different port - indicates symmetric NAT
|
|
181
|
+
await clock.tickAsync(10);
|
|
182
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1', port: 2000, relatedPort: 3478}});
|
|
183
|
+
|
|
184
|
+
assert.equal(emittedEvents[Events.natTypeUpdated].length, 1);
|
|
185
|
+
assert.deepEqual(emittedEvents[Events.natTypeUpdated][0], {
|
|
186
|
+
natType: 'symmetric-nat',
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
clusterReachability.abort();
|
|
190
|
+
await promise;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('emits only the first successful UDP result when enablePerUdpUrlReachability is true', async () => {
|
|
194
|
+
const perUdpClusterReachability = new ClusterReachability(
|
|
195
|
+
'testName',
|
|
96
196
|
{
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
197
|
+
isVideoMesh: false,
|
|
198
|
+
udp: ['stun:udp1', 'stun:udp2'],
|
|
199
|
+
tcp: [],
|
|
200
|
+
xtls: [],
|
|
100
201
|
},
|
|
202
|
+
true
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
const udpEvents: ResultEventData[] = [];
|
|
206
|
+
perUdpClusterReachability.on(Events.resultReady, (data: ResultEventData) => {
|
|
207
|
+
udpEvents.push(data);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const udpRpc1 = (perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp[0];
|
|
211
|
+
const udpRpc2 = (perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp[1];
|
|
212
|
+
|
|
213
|
+
udpRpc1.emit({file: 'test', function: 'test'}, ReachabilityPeerConnectionEvents.resultReady, {
|
|
214
|
+
protocol: 'udp',
|
|
215
|
+
result: 'reachable',
|
|
216
|
+
latencyInMilliseconds: 50,
|
|
217
|
+
clientMediaIPs: ['1.1.1.1'],
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
udpRpc2.emit({file: 'test', function: 'test'}, ReachabilityPeerConnectionEvents.resultReady, {
|
|
221
|
+
protocol: 'udp',
|
|
222
|
+
result: 'reachable',
|
|
223
|
+
latencyInMilliseconds: 30,
|
|
224
|
+
clientMediaIPs: ['2.2.2.2'],
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
assert.equal(udpEvents.length, 1);
|
|
228
|
+
assert.equal(udpEvents[0].latencyInMilliseconds, 50);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
describe('#subnet collection', () => {
|
|
233
|
+
let clock;
|
|
234
|
+
|
|
235
|
+
beforeEach(() => {
|
|
236
|
+
clock = sinon.useFakeTimers();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
afterEach(() => {
|
|
240
|
+
clock.restore();
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('collects reached subnets from ReachabilityPeerConnection events', async () => {
|
|
244
|
+
const promise = clusterReachability.start();
|
|
245
|
+
|
|
246
|
+
await clock.tickAsync(10);
|
|
247
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:192.168.1.1:5004'}});
|
|
248
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:10.0.0.1:5004'}});
|
|
249
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'relay.server.ip'}});
|
|
250
|
+
|
|
251
|
+
clusterReachability.abort();
|
|
252
|
+
await promise;
|
|
253
|
+
|
|
254
|
+
assert.equal(clusterReachability.reachedSubnets.size, 3);
|
|
255
|
+
assert.isTrue(clusterReachability.reachedSubnets.has('192.168.1.1'));
|
|
256
|
+
assert.isTrue(clusterReachability.reachedSubnets.has('10.0.0.1'));
|
|
257
|
+
assert.isTrue(clusterReachability.reachedSubnets.has('relay.server.ip'));
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('stores only unique subnet addresses', async () => {
|
|
261
|
+
const promise = clusterReachability.start();
|
|
262
|
+
|
|
263
|
+
await clock.tickAsync(10);
|
|
264
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:192.168.1.1:5004'}});
|
|
265
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:192.168.1.1:9000'}});
|
|
266
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: '192.168.1.1'}});
|
|
267
|
+
|
|
268
|
+
clusterReachability.abort();
|
|
269
|
+
await promise;
|
|
270
|
+
|
|
271
|
+
// Should have only 1 unique subnet
|
|
272
|
+
assert.equal(clusterReachability.reachedSubnets.size, 1);
|
|
273
|
+
assert.isTrue(clusterReachability.reachedSubnets.has('192.168.1.1'));
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('accumulates subnets from multiple candidates', async () => {
|
|
277
|
+
const promise = clusterReachability.start();
|
|
278
|
+
|
|
279
|
+
await clock.tickAsync(10);
|
|
280
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:192.168.1.1:5004'}});
|
|
281
|
+
|
|
282
|
+
await clock.tickAsync(10);
|
|
283
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', url: 'stun:10.0.0.1:5004'}});
|
|
284
|
+
|
|
285
|
+
await clock.tickAsync(10);
|
|
286
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: '172.16.0.1'}});
|
|
287
|
+
|
|
288
|
+
clusterReachability.abort();
|
|
289
|
+
await promise;
|
|
290
|
+
|
|
291
|
+
assert.equal(clusterReachability.reachedSubnets.size, 3);
|
|
292
|
+
assert.deepEqual(Array.from(clusterReachability.reachedSubnets), ['192.168.1.1', '10.0.0.1', '172.16.0.1']);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('collects reached subnets from all peer connections when enablePerUdpUrlReachability is true', async () => {
|
|
296
|
+
const perUdpClusterReachability = new ClusterReachability(
|
|
297
|
+
'testName',
|
|
101
298
|
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
299
|
+
isVideoMesh: false,
|
|
300
|
+
udp: ['stun:udp1', 'stun:udp2'],
|
|
301
|
+
tcp: ['stun:tcp1.webex.com'],
|
|
302
|
+
xtls: [],
|
|
105
303
|
},
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
304
|
+
true
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
const udpRpc1 = (perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp[0];
|
|
308
|
+
const udpRpc2 = (perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp[1];
|
|
309
|
+
const tcpTlsRpc = (perUdpClusterReachability as any).reachabilityPeerConnection;
|
|
310
|
+
|
|
311
|
+
udpRpc1.emit({file: 'test', function: 'test'}, ReachabilityPeerConnectionEvents.reachedSubnets, {
|
|
312
|
+
subnets: ['192.168.1.1'],
|
|
313
|
+
});
|
|
314
|
+
udpRpc2.emit({file: 'test', function: 'test'}, ReachabilityPeerConnectionEvents.reachedSubnets, {
|
|
315
|
+
subnets: ['10.0.0.1'],
|
|
316
|
+
});
|
|
317
|
+
tcpTlsRpc.emit({file: 'test', function: 'test'}, ReachabilityPeerConnectionEvents.reachedSubnets, {
|
|
318
|
+
subnets: ['172.16.0.1'],
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
assert.equal(perUdpClusterReachability.reachedSubnets.size, 3);
|
|
322
|
+
assert.isTrue(perUdpClusterReachability.reachedSubnets.has('192.168.1.1'));
|
|
323
|
+
assert.isTrue(perUdpClusterReachability.reachedSubnets.has('10.0.0.1'));
|
|
324
|
+
assert.isTrue(perUdpClusterReachability.reachedSubnets.has('172.16.0.1'));
|
|
109
325
|
});
|
|
110
326
|
});
|
|
111
327
|
|
|
112
|
-
|
|
113
|
-
(
|
|
328
|
+
describe('#delegation', () => {
|
|
329
|
+
it('delegates getResult() to ReachabilityPeerConnection', () => {
|
|
330
|
+
const rpcGetResultStub = sinon.stub(clusterReachability.reachabilityPeerConnection, 'getResult').returns({
|
|
331
|
+
udp: {result: 'reachable', latencyInMilliseconds: 42},
|
|
332
|
+
tcp: {result: 'unreachable'},
|
|
333
|
+
xtls: {result: 'untested'},
|
|
334
|
+
});
|
|
114
335
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
336
|
+
const result = clusterReachability.getResult();
|
|
337
|
+
|
|
338
|
+
assert.calledOnce(rpcGetResultStub);
|
|
339
|
+
assert.equal(result.udp.result, 'reachable');
|
|
340
|
+
assert.equal(result.udp.latencyInMilliseconds, 42);
|
|
120
341
|
});
|
|
121
342
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
343
|
+
it('delegates abort() to ReachabilityPeerConnection', () => {
|
|
344
|
+
const rpcAbortStub = sinon.stub(clusterReachability.reachabilityPeerConnection, 'abort');
|
|
345
|
+
|
|
346
|
+
clusterReachability.abort();
|
|
347
|
+
|
|
348
|
+
assert.calledOnce(rpcAbortStub);
|
|
126
349
|
});
|
|
127
|
-
});
|
|
128
350
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
351
|
+
it('delegates start() to ReachabilityPeerConnection and returns result', async () => {
|
|
352
|
+
const expectedResult = {
|
|
353
|
+
udp: {result: 'reachable'},
|
|
354
|
+
tcp: {result: 'unreachable'},
|
|
355
|
+
xtls: {result: 'unreachable'},
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const rpcStartStub = sinon.stub(clusterReachability.reachabilityPeerConnection, 'start').resolves();
|
|
359
|
+
const rpcGetResultStub = sinon.stub(clusterReachability.reachabilityPeerConnection, 'getResult').returns(expectedResult);
|
|
360
|
+
|
|
361
|
+
const result = await clusterReachability.start();
|
|
362
|
+
|
|
363
|
+
assert.calledOnce(rpcStartStub);
|
|
364
|
+
assert.calledOnce(rpcGetResultStub);
|
|
365
|
+
assert.deepEqual(result, expectedResult);
|
|
134
366
|
});
|
|
135
367
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
368
|
+
it('delegates start() and abort() to all peer connections when enablePerUdpUrlReachability is true', async () => {
|
|
369
|
+
const perUdpClusterReachability = new ClusterReachability(
|
|
370
|
+
'testName',
|
|
371
|
+
{
|
|
372
|
+
isVideoMesh: false,
|
|
373
|
+
udp: ['stun:udp1', 'stun:udp2'],
|
|
374
|
+
tcp: ['stun:tcp1.webex.com'],
|
|
375
|
+
xtls: [],
|
|
376
|
+
},
|
|
377
|
+
true
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
const udpRpc1 = (perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp[0];
|
|
381
|
+
const udpRpc2 = (perUdpClusterReachability as any).reachabilityPeerConnectionsForUdp[1];
|
|
382
|
+
const tcpTlsRpc = (perUdpClusterReachability as any).reachabilityPeerConnection;
|
|
383
|
+
|
|
384
|
+
const startStub1 = sinon.stub(udpRpc1, 'start').resolves({udp: {result: 'reachable'}});
|
|
385
|
+
const startStub2 = sinon.stub(udpRpc2, 'start').resolves({udp: {result: 'unreachable'}});
|
|
386
|
+
const startStubTcp = sinon.stub(tcpTlsRpc, 'start').resolves({tcp: {result: 'reachable'}});
|
|
387
|
+
|
|
388
|
+
const abortStub1 = sinon.stub(udpRpc1, 'abort');
|
|
389
|
+
const abortStub2 = sinon.stub(udpRpc2, 'abort');
|
|
390
|
+
const abortStubTcp = sinon.stub(tcpTlsRpc, 'abort');
|
|
391
|
+
|
|
392
|
+
await perUdpClusterReachability.start();
|
|
393
|
+
|
|
394
|
+
assert.calledOnce(startStub1);
|
|
395
|
+
assert.calledOnce(startStub2);
|
|
396
|
+
assert.calledOnce(startStubTcp);
|
|
397
|
+
|
|
398
|
+
perUdpClusterReachability.abort();
|
|
399
|
+
|
|
400
|
+
assert.calledOnce(abortStub1);
|
|
401
|
+
assert.calledOnce(abortStub2);
|
|
402
|
+
assert.calledOnce(abortStubTcp);
|
|
403
|
+
});
|
|
139
404
|
});
|
|
140
405
|
|
|
141
|
-
describe('#
|
|
406
|
+
describe('#WebRTC peer connection setup', () => {
|
|
142
407
|
let clock;
|
|
143
408
|
|
|
144
409
|
beforeEach(() => {
|
|
@@ -149,6 +414,37 @@ describe('ClusterReachability', () => {
|
|
|
149
414
|
clock.restore();
|
|
150
415
|
});
|
|
151
416
|
|
|
417
|
+
it('should create a peer connection with the right config', () => {
|
|
418
|
+
assert.calledOnceWithExactly(global.RTCPeerConnection, {
|
|
419
|
+
iceServers: [
|
|
420
|
+
{username: '', credential: '', urls: ['stun:udp1']},
|
|
421
|
+
{username: '', credential: '', urls: ['stun:udp2']},
|
|
422
|
+
{
|
|
423
|
+
username: 'webexturnreachuser',
|
|
424
|
+
credential: 'webexturnreachpwd',
|
|
425
|
+
urls: ['turn:tcp1.webex.com?transport=tcp'],
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
username: 'webexturnreachuser',
|
|
429
|
+
credential: 'webexturnreachpwd',
|
|
430
|
+
urls: ['turn:tcp2.webex.com:5004?transport=tcp'],
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
username: 'webexturnreachuser',
|
|
434
|
+
credential: 'webexturnreachpwd',
|
|
435
|
+
urls: ['turns:xtls1.webex.com?transport=tcp'],
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
username: 'webexturnreachuser',
|
|
439
|
+
credential: 'webexturnreachpwd',
|
|
440
|
+
urls: ['turns:xtls2.webex.com:443?transport=tcp'],
|
|
441
|
+
},
|
|
442
|
+
],
|
|
443
|
+
iceCandidatePoolSize: 0,
|
|
444
|
+
iceTransportPolicy: 'all',
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
|
|
152
448
|
it('should initiate the ICE gathering process', async () => {
|
|
153
449
|
const promise = clusterReachability.start();
|
|
154
450
|
|
|
@@ -174,6 +470,40 @@ describe('ClusterReachability', () => {
|
|
|
174
470
|
assert.deepEqual(emittedEvents[Events.clientMediaIpsUpdated], []);
|
|
175
471
|
});
|
|
176
472
|
|
|
473
|
+
it('resolves when ICE gathering is completed', async () => {
|
|
474
|
+
const promise = clusterReachability.start();
|
|
475
|
+
|
|
476
|
+
await testUtils.flushPromises();
|
|
477
|
+
|
|
478
|
+
fakePeerConnection.iceGatheringState = 'complete';
|
|
479
|
+
fakePeerConnection.onicegatheringstatechange();
|
|
480
|
+
await promise;
|
|
481
|
+
|
|
482
|
+
assert.deepEqual(clusterReachability.getResult(), {
|
|
483
|
+
udp: {result: 'unreachable'},
|
|
484
|
+
tcp: {result: 'unreachable'},
|
|
485
|
+
xtls: {result: 'unreachable'},
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
it('resolves with the right result when ICE gathering is completed', async () => {
|
|
490
|
+
const promise = clusterReachability.start();
|
|
491
|
+
|
|
492
|
+
// send 1 candidate
|
|
493
|
+
await clock.tickAsync(30);
|
|
494
|
+
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
495
|
+
|
|
496
|
+
fakePeerConnection.iceGatheringState = 'complete';
|
|
497
|
+
fakePeerConnection.onicegatheringstatechange();
|
|
498
|
+
await promise;
|
|
499
|
+
|
|
500
|
+
assert.deepEqual(clusterReachability.getResult(), {
|
|
501
|
+
udp: {result: 'reachable', latencyInMilliseconds: 30, clientMediaIPs: ['somePublicIp1']},
|
|
502
|
+
tcp: {result: 'unreachable'},
|
|
503
|
+
xtls: {result: 'unreachable'},
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
177
507
|
it('resolves and returns correct results when aborted before it gets any candidates', async () => {
|
|
178
508
|
const promise = clusterReachability.start();
|
|
179
509
|
|
|
@@ -216,39 +546,17 @@ describe('ClusterReachability', () => {
|
|
|
216
546
|
xtls: {result: 'unreachable'},
|
|
217
547
|
});
|
|
218
548
|
});
|
|
549
|
+
});
|
|
219
550
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
await testUtils.flushPromises();
|
|
224
|
-
|
|
225
|
-
fakePeerConnection.iceGatheringState = 'complete';
|
|
226
|
-
fakePeerConnection.onicegatheringstatechange();
|
|
227
|
-
await promise;
|
|
551
|
+
describe('#latency and candidate handling', () => {
|
|
552
|
+
let clock;
|
|
228
553
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
tcp: {result: 'unreachable'},
|
|
232
|
-
xtls: {result: 'unreachable'},
|
|
233
|
-
});
|
|
554
|
+
beforeEach(() => {
|
|
555
|
+
clock = sinon.useFakeTimers();
|
|
234
556
|
});
|
|
235
557
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
// send 1 candidate
|
|
240
|
-
await clock.tickAsync(30);
|
|
241
|
-
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
242
|
-
|
|
243
|
-
fakePeerConnection.iceGatheringState = 'complete';
|
|
244
|
-
fakePeerConnection.onicegatheringstatechange();
|
|
245
|
-
await promise;
|
|
246
|
-
|
|
247
|
-
assert.deepEqual(clusterReachability.getResult(), {
|
|
248
|
-
udp: {result: 'reachable', latencyInMilliseconds: 30, clientMediaIPs: ['somePublicIp1']},
|
|
249
|
-
tcp: {result: 'unreachable'},
|
|
250
|
-
xtls: {result: 'unreachable'},
|
|
251
|
-
});
|
|
558
|
+
afterEach(() => {
|
|
559
|
+
clock.restore();
|
|
252
560
|
});
|
|
253
561
|
|
|
254
562
|
it('should store latency only for the first srflx candidate, but IPs from all of them', async () => {
|
|
@@ -257,17 +565,16 @@ describe('ClusterReachability', () => {
|
|
|
257
565
|
await clock.tickAsync(10);
|
|
258
566
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp1'}});
|
|
259
567
|
|
|
260
|
-
//
|
|
261
|
-
await clock.tickAsync(10);
|
|
568
|
+
await clock.tickAsync(50); // total elapsed time: 60
|
|
262
569
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp2'}});
|
|
263
570
|
|
|
264
|
-
await clock.tickAsync(10);
|
|
571
|
+
await clock.tickAsync(10); // total elapsed time: 70
|
|
265
572
|
fakePeerConnection.onicecandidate({candidate: {type: 'srflx', address: 'somePublicIp3'}});
|
|
266
573
|
|
|
267
574
|
clusterReachability.abort();
|
|
268
575
|
await promise;
|
|
269
576
|
|
|
270
|
-
// latency should be from only the first candidates, but the clientMediaIps should be from all UDP candidates
|
|
577
|
+
// latency should be from only the first candidates, but the clientMediaIps should be from all UDP candidates
|
|
271
578
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
272
579
|
udp: {
|
|
273
580
|
result: 'reachable',
|
|
@@ -283,19 +590,18 @@ describe('ClusterReachability', () => {
|
|
|
283
590
|
const promise = clusterReachability.start();
|
|
284
591
|
|
|
285
592
|
await clock.tickAsync(10);
|
|
286
|
-
fakePeerConnection.onicecandidate({
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
await clock.tickAsync(10);
|
|
290
|
-
fakePeerConnection.onicecandidate({candidate: {type: 'relay', address: 'someTurnRelayIp2'}});
|
|
593
|
+
fakePeerConnection.onicecandidate({
|
|
594
|
+
candidate: {type: 'relay', address: 'relayIp1', port: 3478},
|
|
595
|
+
});
|
|
291
596
|
|
|
292
|
-
await clock.tickAsync(
|
|
293
|
-
fakePeerConnection.onicecandidate({
|
|
597
|
+
await clock.tickAsync(50); // total elapsed time: 60
|
|
598
|
+
fakePeerConnection.onicecandidate({
|
|
599
|
+
candidate: {type: 'relay', address: 'relayIp2', port: 3478},
|
|
600
|
+
});
|
|
294
601
|
|
|
295
602
|
clusterReachability.abort();
|
|
296
603
|
await promise;
|
|
297
604
|
|
|
298
|
-
// latency should be from only the first candidates, but the clientMediaIps should be from only from UDP candidates
|
|
299
605
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
300
606
|
udp: {result: 'unreachable'},
|
|
301
607
|
tcp: {result: 'reachable', latencyInMilliseconds: 10},
|
|
@@ -308,24 +614,17 @@ describe('ClusterReachability', () => {
|
|
|
308
614
|
|
|
309
615
|
await clock.tickAsync(10);
|
|
310
616
|
fakePeerConnection.onicecandidate({
|
|
311
|
-
candidate: {type: 'relay', address: '
|
|
617
|
+
candidate: {type: 'relay', address: 'relayIp1', port: 443},
|
|
312
618
|
});
|
|
313
619
|
|
|
314
|
-
//
|
|
315
|
-
await clock.tickAsync(10);
|
|
620
|
+
await clock.tickAsync(50); // total elapsed time: 60
|
|
316
621
|
fakePeerConnection.onicecandidate({
|
|
317
|
-
candidate: {type: 'relay', address: '
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
await clock.tickAsync(10);
|
|
321
|
-
fakePeerConnection.onicecandidate({
|
|
322
|
-
candidate: {type: 'relay', address: 'someTurnRelayIp3', port: 443},
|
|
622
|
+
candidate: {type: 'relay', address: 'relayIp2', port: 443},
|
|
323
623
|
});
|
|
324
624
|
|
|
325
625
|
clusterReachability.abort();
|
|
326
626
|
await promise;
|
|
327
627
|
|
|
328
|
-
// latency should be from only the first candidates, but the clientMediaIps should be from only from UDP candidates
|
|
329
628
|
assert.deepEqual(clusterReachability.getResult(), {
|
|
330
629
|
udp: {result: 'unreachable'},
|
|
331
630
|
tcp: {result: 'unreachable'},
|
|
@@ -440,37 +739,5 @@ describe('ClusterReachability', () => {
|
|
|
440
739
|
xtls: {result: 'reachable', latencyInMilliseconds: 20},
|
|
441
740
|
});
|
|
442
741
|
});
|
|
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
|
-
});
|
|
475
742
|
});
|
|
476
|
-
});
|
|
743
|
+
});
|
|
@@ -1693,7 +1693,7 @@ describe('gatherReachability', () => {
|
|
|
1693
1693
|
udp: ['testUDP1', 'testUDP2'],
|
|
1694
1694
|
tcp: [], // empty list because TCP is disabled in config
|
|
1695
1695
|
xtls: ['testXTLS1', 'testXTLS2'],
|
|
1696
|
-
});
|
|
1696
|
+
}, undefined);
|
|
1697
1697
|
});
|
|
1698
1698
|
|
|
1699
1699
|
it('does not do TLS reachability if it is disabled in config', async () => {
|
|
@@ -1728,7 +1728,7 @@ describe('gatherReachability', () => {
|
|
|
1728
1728
|
udp: ['testUDP1', 'testUDP2'],
|
|
1729
1729
|
tcp: ['testTCP1', 'testTCP2'],
|
|
1730
1730
|
xtls: [], // empty list because TLS is disabled in config
|
|
1731
|
-
});
|
|
1731
|
+
}, undefined);
|
|
1732
1732
|
});
|
|
1733
1733
|
|
|
1734
1734
|
it('does not do TCP or TLS reachability if it is disabled in config', async () => {
|
|
@@ -1763,7 +1763,7 @@ describe('gatherReachability', () => {
|
|
|
1763
1763
|
udp: ['testUDP1', 'testUDP2'],
|
|
1764
1764
|
tcp: [], // empty list because TCP is disabled in config
|
|
1765
1765
|
xtls: [], // empty list because TLS is disabled in config
|
|
1766
|
-
});
|
|
1766
|
+
}, undefined);
|
|
1767
1767
|
});
|
|
1768
1768
|
|
|
1769
1769
|
it('retry of getClusters is succesfull', async () => {
|