diff --git a/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics-latencies.ts b/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics-latencies.ts index 84f577ef2bd..3e8b42966a5 100644 --- a/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +++ b/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics-latencies.ts @@ -303,10 +303,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin { * @returns - latency */ public getStayLobbyTime() { - return this.getDiffBetweenTimestamps( - 'client.locus.join.response', - 'internal.host.meeting.participant.admitted' - ); + return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.lobby.exited'); } /** @@ -480,7 +477,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin { const clickToInterstitial = this.getClickToInterstitial(); const interstitialToJoinOk = this.getInterstitialToJoinOK(); const joinConfJMT = this.getJoinConfJMT(); - const lobbyTime = this.getStayLobbyTime(); + const lobbyTimeLatency = this.getStayLobbyTime(); + const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0; if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) { const totalMediaJMT = clamp( diff --git a/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics.util.ts b/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics.util.ts index 064008516d7..e5003a6dae9 100644 --- a/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics.util.ts +++ b/packages/@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics.util.ts @@ -361,7 +361,6 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => { joinTimes.totalMediaJMT = cdl.getTotalMediaJMT(); joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT(); joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady(); - joinTimes.stayLobbyTime = cdl.getStayLobbyTime(); joinTimes.totalMediaJMTWithUserDelay = cdl.getTotalMediaJMTWithUserDelay(); joinTimes.totalJMTWithUserDelay = cdl.getTotalJMTWithUserDelay(); break; @@ -369,6 +368,11 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => { case 'client.media.tx.start': audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart(); videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart(); + break; + + case 'client.lobby.exited': + joinTimes.stayLobbyTime = cdl.getStayLobbyTime(); + break; } if (!isEmpty(joinTimes)) { diff --git a/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts b/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts index df43c1263dd..2b628cffb6d 100644 --- a/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +++ b/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts @@ -142,9 +142,7 @@ describe('plugin-metrics', () => { webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon .stub() .returns(10); - webex.internal.newMetrics.callDiagnosticLatencies.getU2CTime = sinon - .stub() - .returns(20); + webex.internal.newMetrics.callDiagnosticLatencies.getU2CTime = sinon.stub().returns(20); webex.internal.newMetrics.callDiagnosticLatencies.getReachabilityClustersReqResp = sinon .stub() .returns(10); @@ -165,7 +163,7 @@ describe('plugin-metrics', () => { registerWDMDeviceJMT: 10, showInterstitialTime: 10, getU2CTime: 20, - getReachabilityClustersReqResp: 10 + getReachabilityClustersReqResp: 10, }, }); assert.lengthOf( @@ -189,9 +187,8 @@ describe('plugin-metrics', () => { webex.internal.newMetrics.callDiagnosticLatencies.getDownloadTimeJMT = sinon .stub() .returns(100); - webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitialWithUserDelay = sinon - .stub() - .returns(43); + webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitialWithUserDelay = + sinon.stub().returns(43); webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMTWithUserDelay = sinon .stub() .returns(64); @@ -346,7 +343,7 @@ describe('plugin-metrics', () => { webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToJoinOK = sinon .stub() .returns(7); - webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon + webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon .stub() .returns(1); webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMTWithUserDelay = sinon @@ -372,7 +369,6 @@ describe('plugin-metrics', () => { totalMediaJMT: 61, interstitialToMediaOKJMT: 22, callInitMediaEngineReady: 10, - stayLobbyTime: 1, totalMediaJMTWithUserDelay: 43, totalJMTWithUserDelay: 64, }, @@ -382,6 +378,34 @@ describe('plugin-metrics', () => { 0 ); }); + + it('appends the correct join times to the request for client.lobby.exited', async () => { + webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon + .stub() + .returns(10); + + const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics( + //@ts-ignore + {event: {name: 'client.lobby.exited'}} + ); + await flushPromises(); + clock.tick(config.metrics.batcherWait); + + await promise; + + //@ts-ignore + assert.calledOnce(webex.request); + assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, { + name: 'client.lobby.exited', + joinTimes: { + stayLobbyTime: 10, + }, + }); + assert.lengthOf( + webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, + 0 + ); + }); }); describe('when the request fails', () => { diff --git a/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts b/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts index 9a1e786a8e0..17499eee22e 100644 --- a/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +++ b/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts @@ -143,7 +143,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.removed', value: 50}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { minimum: 0, - maximum: 100 + maximum: 100, }); assert.deepEqual(res, 40); }); @@ -153,7 +153,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.removed', value: 45}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { minimum: 10, - maximum: 100 + maximum: 100, }); assert.deepEqual(res, 10); }); @@ -163,7 +163,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.removed', value: 210}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { minimum: 0, - maximum: 100 + maximum: 100, }); assert.deepEqual(res, 100); }); @@ -172,7 +172,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.displayed', value: 50}); cdl.saveTimestamp({key: 'client.alert.removed', value: 45}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { - maximum: 100 + maximum: 100, }); assert.deepEqual(res, 0); }); @@ -181,7 +181,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.displayed', value: 10}); cdl.saveTimestamp({key: 'client.alert.removed', value: 2000}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { - minimum: 5 + minimum: 5, }); assert.deepEqual(res, 1990); }); @@ -191,7 +191,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.removed', value: 50}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { minimum: 10, - maximum: 1000 + maximum: 1000, }); assert.deepEqual(res, 10); }); @@ -200,7 +200,7 @@ describe('internal-plugin-metrics', () => { cdl.saveTimestamp({key: 'client.alert.displayed', value: 10}); const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', { minimum: 0, - maximum: 100 + maximum: 100, }); assert.deepEqual(res, undefined); }); @@ -513,7 +513,7 @@ describe('internal-plugin-metrics', () => { value: 10, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 20, }); assert.deepEqual(cdl.getStayLobbyTime(), 10); @@ -656,56 +656,56 @@ describe('internal-plugin-metrics', () => { }); it('calculates getTotalJMT correctly when clickToInterstitial is 0', () => { - cdl.saveLatency('internal.click.to.interstitial', 0); - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 20, - }); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMT(), 20); + cdl.saveLatency('internal.click.to.interstitial', 0); + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 20, }); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, + }); + assert.deepEqual(cdl.getTotalJMT(), 20); + }); - it('calculates getTotalJMT correctly when interstitialToJoinOk is 0', () => { - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 40, - }); - cdl.saveLatency('internal.click.to.interstitial', 12); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMT(), 12); + it('calculates getTotalJMT correctly when interstitialToJoinOk is 0', () => { + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 40, + }); + cdl.saveLatency('internal.click.to.interstitial', 12); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, }); + assert.deepEqual(cdl.getTotalJMT(), 12); + }); - it('calculates getTotalJMT correctly when both clickToInterstitial and interstitialToJoinOk are 0', () => { - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 40, - }); - cdl.saveLatency('internal.click.to.interstitial', 0); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMT(), 0); + it('calculates getTotalJMT correctly when both clickToInterstitial and interstitialToJoinOk are 0', () => { + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 40, }); + cdl.saveLatency('internal.click.to.interstitial', 0); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, + }); + assert.deepEqual(cdl.getTotalJMT(), 0); + }); - it('calculates getTotalJMT correctly when both clickToInterstitial is not a number', () => { - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 40, - }); - cdl.saveLatency('internal.click.to.interstitial', 'eleven' as unknown as number); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMT(), undefined); + it('calculates getTotalJMT correctly when both clickToInterstitial is not a number', () => { + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 40, }); + cdl.saveLatency('internal.click.to.interstitial', 'eleven' as unknown as number); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, + }); + assert.deepEqual(cdl.getTotalJMT(), undefined); + }); it('calculates getTotalJMT correctly when it is greater than MAX_INTEGER', () => { cdl.saveTimestamp({ @@ -740,70 +740,73 @@ describe('internal-plugin-metrics', () => { assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 45); }); - it('calculates getTotalJMTWithUserDelay correctly when clickToInterstitialWithUserDelay is 0', () => { - cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0); - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 20, - }); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 20); + it('calculates getTotalJMTWithUserDelay correctly when clickToInterstitialWithUserDelay is 0', () => { + cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0); + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 20, + }); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, }); + assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 20); + }); - it('calculates getTotalJMTWithUserDelay correctly when interstitialToJoinOk is 0', () => { - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 40, - }); - cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 12); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 12); + it('calculates getTotalJMTWithUserDelay correctly when interstitialToJoinOk is 0', () => { + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 40, + }); + cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 12); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, }); + assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 12); + }); - it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay and interstitialToJoinOk are 0', () => { - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 40, - }); - cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 0); + it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay and interstitialToJoinOk are 0', () => { + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 40, }); + cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, + }); + assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 0); + }); - it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay is not a number', () => { - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 40, - }); - cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 'eleven' as unknown as number); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMTWithUserDelay(), undefined); + it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay is not a number', () => { + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 40, + }); + cdl.saveLatency( + 'internal.click.to.interstitial.with.user.delay', + 'eleven' as unknown as number + ); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, }); + assert.deepEqual(cdl.getTotalJMTWithUserDelay(), undefined); + }); - it('calculates getTotalJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => { - cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648); - cdl.saveTimestamp({ - key: 'internal.client.interstitial-window.click.joinbutton', - value: 20, - }); - cdl.saveTimestamp({ - key: 'client.locus.join.response', - value: 40, - }); - assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 2147483647); + it('calculates getTotalJMTWithUserDelay correctly when it is greater than MAX_INTEGER', () => { + cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 2147483648); + cdl.saveTimestamp({ + key: 'internal.client.interstitial-window.click.joinbutton', + value: 20, }); + cdl.saveTimestamp({ + key: 'client.locus.join.response', + value: 40, + }); + assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 2147483647); + }); it('calculates getTotalMediaJMT correctly', () => { cdl.saveTimestamp({ @@ -827,7 +830,7 @@ describe('internal-plugin-metrics', () => { value: 20, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 24, }); cdl.saveTimestamp({ @@ -863,7 +866,7 @@ describe('internal-plugin-metrics', () => { value: 2147483700, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 2147483800, }); cdl.saveTimestamp({ @@ -900,7 +903,7 @@ describe('internal-plugin-metrics', () => { value: 20, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 24, }); cdl.saveTimestamp({ @@ -937,7 +940,7 @@ describe('internal-plugin-metrics', () => { value: 2147483700, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 2147483800, }); cdl.saveTimestamp({ @@ -1041,20 +1044,20 @@ describe('internal-plugin-metrics', () => { // the maximum possible sum is 2400000, which is less than MAX_INTEGER (2147483647). // This test should verify that the final clamping works by mocking the intermediate methods // to return values that would sum to more than MAX_INTEGER. - + const originalGetJoinReqResp = cdl.getJoinReqResp; const originalGetICESetupTime = cdl.getICESetupTime; - + // Mock the methods to return large values that would exceed MAX_INTEGER when summed cdl.getJoinReqResp = () => 1500000000; cdl.getICESetupTime = () => 1000000000; - + const result = cdl.getJoinConfJMT(); - + // Restore original methods cdl.getJoinReqResp = originalGetJoinReqResp; cdl.getICESetupTime = originalGetICESetupTime; - + assert.deepEqual(result, 2147483647); }); @@ -1140,7 +1143,7 @@ describe('internal-plugin-metrics', () => { value: 10, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 12, }); cdl.saveTimestamp({ @@ -1160,7 +1163,7 @@ describe('internal-plugin-metrics', () => { value: 10, }); cdl.saveTimestamp({ - key: 'internal.host.meeting.participant.admitted', + key: 'client.lobby.exited', value: 12, }); cdl.saveTimestamp({ diff --git a/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts b/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts index 406ea91019b..53e5009d15c 100644 --- a/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +++ b/packages/@webex/internal-plugin-metrics/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts @@ -311,7 +311,7 @@ describe('internal-plugin-metrics', () => { origin: { buildType: 'prod', networkType: 'unknown', - upgradeChannel: expectedUpgradeChannel + upgradeChannel: expectedUpgradeChannel, }, event: {name: eventName, ...expectedEvent}, }, @@ -393,7 +393,7 @@ describe('internal-plugin-metrics', () => { totalJmt: undefined, clientJmt: undefined, downloadTime: undefined, - clickToInterstitialWithUserDelay: undefined, + clickToInterstitialWithUserDelay: undefined, totalJMTWithUserDelay: undefined, }, }, @@ -430,7 +430,6 @@ describe('internal-plugin-metrics', () => { totalMediaJMT: undefined, interstitialToMediaOKJMT: undefined, callInitMediaEngineReady: undefined, - stayLobbyTime: undefined, totalMediaJMTWithUserDelay: undefined, totalJMTWithUserDelay: undefined, }, @@ -447,6 +446,14 @@ describe('internal-plugin-metrics', () => { }, }, ], + [ + 'client.lobby.exited', + { + joinTimes: { + stayLobbyTime: undefined, + }, + }, + ], ].forEach(([eventName, expectedEvent]) => { it(`returns expected result for ${eventName}`, () => { check(eventName as string, expectedEvent, 'gold');