2023-05-14 02:27:01 +08:00
|
|
|
import { GroupCallStatsReport } from "matrix-js-sdk/src/webrtc/groupCall";
|
|
|
|
import {
|
|
|
|
AudioConcealment,
|
2023-06-06 14:28:53 +08:00
|
|
|
ByteSentStatsReport,
|
2023-05-14 02:27:01 +08:00
|
|
|
ConnectionStatsReport,
|
|
|
|
} from "matrix-js-sdk/src/webrtc/stats/statsReport";
|
2023-04-05 16:25:26 +08:00
|
|
|
import { ObjectFlattener } from "../../src/otel/ObjectFlattener";
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copyright 2023 New Vector Ltd
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
describe("ObjectFlattener", () => {
|
2023-05-14 02:27:01 +08:00
|
|
|
const noConcealment: AudioConcealment = {
|
|
|
|
concealedAudio: 0,
|
|
|
|
totalAudioDuration: 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
const statsReport: GroupCallStatsReport<ConnectionStatsReport> = {
|
2023-04-05 16:25:26 +08:00
|
|
|
report: {
|
2023-06-06 14:28:53 +08:00
|
|
|
callId: "callId",
|
|
|
|
opponentMemberId: "opponentMemberId",
|
2023-04-05 16:25:26 +08:00
|
|
|
bandwidth: { upload: 426, download: 0 },
|
|
|
|
bitrate: {
|
|
|
|
upload: 426,
|
|
|
|
download: 0,
|
|
|
|
audio: {
|
|
|
|
upload: 124,
|
|
|
|
download: 0,
|
|
|
|
},
|
|
|
|
video: {
|
|
|
|
upload: 302,
|
|
|
|
download: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
packetLoss: {
|
|
|
|
total: 0,
|
|
|
|
download: 0,
|
|
|
|
upload: 0,
|
|
|
|
},
|
|
|
|
framerate: {
|
|
|
|
local: new Map([
|
|
|
|
["LOCAL_AUDIO_TRACK_ID", 0],
|
|
|
|
["LOCAL_VIDEO_TRACK_ID", 30],
|
|
|
|
]),
|
|
|
|
remote: new Map([
|
|
|
|
["REMOTE_AUDIO_TRACK_ID", 0],
|
|
|
|
["REMOTE_VIDEO_TRACK_ID", 60],
|
|
|
|
]),
|
|
|
|
},
|
|
|
|
resolution: {
|
|
|
|
local: new Map([
|
|
|
|
["LOCAL_AUDIO_TRACK_ID", { height: -1, width: -1 }],
|
|
|
|
["LOCAL_VIDEO_TRACK_ID", { height: 460, width: 780 }],
|
|
|
|
]),
|
|
|
|
remote: new Map([
|
|
|
|
["REMOTE_AUDIO_TRACK_ID", { height: -1, width: -1 }],
|
|
|
|
["REMOTE_VIDEO_TRACK_ID", { height: 960, width: 1080 }],
|
|
|
|
]),
|
|
|
|
},
|
2023-04-14 14:49:33 +08:00
|
|
|
jitter: new Map([
|
|
|
|
["REMOTE_AUDIO_TRACK_ID", 2],
|
|
|
|
["REMOTE_VIDEO_TRACK_ID", 50],
|
|
|
|
]),
|
2023-04-05 16:25:26 +08:00
|
|
|
codec: {
|
|
|
|
local: new Map([
|
|
|
|
["LOCAL_AUDIO_TRACK_ID", "opus"],
|
|
|
|
["LOCAL_VIDEO_TRACK_ID", "v8"],
|
|
|
|
]),
|
|
|
|
remote: new Map([
|
|
|
|
["REMOTE_AUDIO_TRACK_ID", "opus"],
|
|
|
|
["REMOTE_VIDEO_TRACK_ID", "v9"],
|
|
|
|
]),
|
|
|
|
},
|
|
|
|
transport: [
|
|
|
|
{
|
|
|
|
ip: "ff11::5fa:abcd:999c:c5c5:50000",
|
|
|
|
type: "udp",
|
|
|
|
localIp: "2aaa:9999:2aaa:999:8888:2aaa:2aaa:7777:50000",
|
|
|
|
isFocus: true,
|
|
|
|
localCandidateType: "host",
|
|
|
|
remoteCandidateType: "host",
|
|
|
|
networkType: "ethernet",
|
|
|
|
rtt: NaN,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
ip: "10.10.10.2:22222",
|
|
|
|
type: "tcp",
|
|
|
|
localIp: "10.10.10.100:33333",
|
|
|
|
isFocus: true,
|
|
|
|
localCandidateType: "srfx",
|
|
|
|
remoteCandidateType: "srfx",
|
|
|
|
networkType: "ethernet",
|
|
|
|
rtt: null,
|
|
|
|
},
|
|
|
|
],
|
2023-05-14 02:27:01 +08:00
|
|
|
audioConcealment: new Map([
|
|
|
|
["REMOTE_AUDIO_TRACK_ID", noConcealment],
|
|
|
|
["REMOTE_VIDEO_TRACK_ID", noConcealment],
|
|
|
|
]),
|
|
|
|
totalAudioConcealment: noConcealment,
|
2023-04-05 16:25:26 +08:00
|
|
|
},
|
|
|
|
};
|
2023-05-14 02:27:01 +08:00
|
|
|
|
2023-04-05 16:25:26 +08:00
|
|
|
describe("on flattenObjectRecursive", () => {
|
|
|
|
it("should flatter an Map object", () => {
|
|
|
|
const flatObject = {};
|
|
|
|
ObjectFlattener.flattenObjectRecursive(
|
|
|
|
statsReport.report.resolution,
|
|
|
|
flatObject,
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.resolution.",
|
2023-04-05 16:25:26 +08:00
|
|
|
0
|
|
|
|
);
|
|
|
|
expect(flatObject).toEqual({
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_AUDIO_TRACK_ID.height":
|
|
|
|
-1,
|
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_AUDIO_TRACK_ID.width":
|
|
|
|
-1,
|
2023-04-05 16:25:26 +08:00
|
|
|
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_VIDEO_TRACK_ID.height": 460,
|
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_VIDEO_TRACK_ID.width": 780,
|
2023-04-05 16:25:26 +08:00
|
|
|
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_AUDIO_TRACK_ID.height":
|
|
|
|
-1,
|
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_AUDIO_TRACK_ID.width":
|
|
|
|
-1,
|
2023-04-05 16:25:26 +08:00
|
|
|
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_VIDEO_TRACK_ID.height": 960,
|
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_VIDEO_TRACK_ID.width": 1080,
|
2023-04-05 16:25:26 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
it("should flatter an Array object", () => {
|
|
|
|
const flatObject = {};
|
|
|
|
ObjectFlattener.flattenObjectRecursive(
|
|
|
|
statsReport.report.transport,
|
|
|
|
flatObject,
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.transport.",
|
2023-04-05 16:25:26 +08:00
|
|
|
0
|
|
|
|
);
|
|
|
|
expect(flatObject).toEqual({
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.transport.0.ip":
|
|
|
|
"ff11::5fa:abcd:999c:c5c5:50000",
|
|
|
|
"matrix.call.stats.connection.transport.0.type": "udp",
|
|
|
|
"matrix.call.stats.connection.transport.0.localIp":
|
2023-04-05 16:25:26 +08:00
|
|
|
"2aaa:9999:2aaa:999:8888:2aaa:2aaa:7777:50000",
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.transport.0.isFocus": true,
|
|
|
|
"matrix.call.stats.connection.transport.0.localCandidateType": "host",
|
|
|
|
"matrix.call.stats.connection.transport.0.remoteCandidateType": "host",
|
|
|
|
"matrix.call.stats.connection.transport.0.networkType": "ethernet",
|
|
|
|
"matrix.call.stats.connection.transport.0.rtt": "NaN",
|
|
|
|
"matrix.call.stats.connection.transport.1.ip": "10.10.10.2:22222",
|
|
|
|
"matrix.call.stats.connection.transport.1.type": "tcp",
|
|
|
|
"matrix.call.stats.connection.transport.1.localIp":
|
|
|
|
"10.10.10.100:33333",
|
|
|
|
"matrix.call.stats.connection.transport.1.isFocus": true,
|
|
|
|
"matrix.call.stats.connection.transport.1.localCandidateType": "srfx",
|
|
|
|
"matrix.call.stats.connection.transport.1.remoteCandidateType": "srfx",
|
|
|
|
"matrix.call.stats.connection.transport.1.networkType": "ethernet",
|
|
|
|
"matrix.call.stats.connection.transport.1.rtt": "null",
|
2023-04-05 16:25:26 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-06-06 14:28:53 +08:00
|
|
|
describe("on flattenReportObject Connection Stats", () => {
|
2023-04-05 16:25:26 +08:00
|
|
|
it("should flatten a Report to otel Attributes Object", () => {
|
|
|
|
expect(
|
2023-06-06 14:28:53 +08:00
|
|
|
ObjectFlattener.flattenReportObject(
|
|
|
|
"matrix.call.stats.connection",
|
|
|
|
statsReport.report
|
|
|
|
)
|
2023-04-05 16:25:26 +08:00
|
|
|
).toEqual({
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.callId": "callId",
|
|
|
|
"matrix.call.stats.connection.opponentMemberId": "opponentMemberId",
|
|
|
|
"matrix.call.stats.connection.bandwidth.download": 0,
|
|
|
|
"matrix.call.stats.connection.bandwidth.upload": 426,
|
|
|
|
"matrix.call.stats.connection.bitrate.audio.download": 0,
|
|
|
|
"matrix.call.stats.connection.bitrate.audio.upload": 124,
|
|
|
|
"matrix.call.stats.connection.bitrate.download": 0,
|
|
|
|
"matrix.call.stats.connection.bitrate.upload": 426,
|
|
|
|
"matrix.call.stats.connection.bitrate.video.download": 0,
|
|
|
|
"matrix.call.stats.connection.bitrate.video.upload": 302,
|
|
|
|
"matrix.call.stats.connection.codec.local.LOCAL_AUDIO_TRACK_ID": "opus",
|
|
|
|
"matrix.call.stats.connection.codec.local.LOCAL_VIDEO_TRACK_ID": "v8",
|
|
|
|
"matrix.call.stats.connection.codec.remote.REMOTE_AUDIO_TRACK_ID":
|
|
|
|
"opus",
|
|
|
|
"matrix.call.stats.connection.codec.remote.REMOTE_VIDEO_TRACK_ID": "v9",
|
|
|
|
"matrix.call.stats.connection.framerate.local.LOCAL_AUDIO_TRACK_ID": 0,
|
|
|
|
"matrix.call.stats.connection.framerate.local.LOCAL_VIDEO_TRACK_ID": 30,
|
|
|
|
"matrix.call.stats.connection.framerate.remote.REMOTE_AUDIO_TRACK_ID": 0,
|
|
|
|
"matrix.call.stats.connection.framerate.remote.REMOTE_VIDEO_TRACK_ID": 60,
|
|
|
|
"matrix.call.stats.connection.jitter.REMOTE_AUDIO_TRACK_ID": 2,
|
|
|
|
"matrix.call.stats.connection.jitter.REMOTE_VIDEO_TRACK_ID": 50,
|
|
|
|
"matrix.call.stats.connection.packetLoss.download": 0,
|
|
|
|
"matrix.call.stats.connection.packetLoss.total": 0,
|
|
|
|
"matrix.call.stats.connection.packetLoss.upload": 0,
|
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_AUDIO_TRACK_ID.height":
|
|
|
|
-1,
|
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_AUDIO_TRACK_ID.width":
|
|
|
|
-1,
|
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_VIDEO_TRACK_ID.height": 460,
|
|
|
|
"matrix.call.stats.connection.resolution.local.LOCAL_VIDEO_TRACK_ID.width": 780,
|
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_AUDIO_TRACK_ID.height":
|
|
|
|
-1,
|
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_AUDIO_TRACK_ID.width":
|
|
|
|
-1,
|
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_VIDEO_TRACK_ID.height": 960,
|
|
|
|
"matrix.call.stats.connection.resolution.remote.REMOTE_VIDEO_TRACK_ID.width": 1080,
|
|
|
|
"matrix.call.stats.connection.transport.0.ip":
|
|
|
|
"ff11::5fa:abcd:999c:c5c5:50000",
|
|
|
|
"matrix.call.stats.connection.transport.0.type": "udp",
|
|
|
|
"matrix.call.stats.connection.transport.0.localIp":
|
2023-04-05 16:25:26 +08:00
|
|
|
"2aaa:9999:2aaa:999:8888:2aaa:2aaa:7777:50000",
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.connection.transport.0.isFocus": true,
|
|
|
|
"matrix.call.stats.connection.transport.0.localCandidateType": "host",
|
|
|
|
"matrix.call.stats.connection.transport.0.remoteCandidateType": "host",
|
|
|
|
"matrix.call.stats.connection.transport.0.networkType": "ethernet",
|
|
|
|
"matrix.call.stats.connection.transport.0.rtt": "NaN",
|
|
|
|
"matrix.call.stats.connection.transport.1.ip": "10.10.10.2:22222",
|
|
|
|
"matrix.call.stats.connection.transport.1.type": "tcp",
|
|
|
|
"matrix.call.stats.connection.transport.1.localIp":
|
|
|
|
"10.10.10.100:33333",
|
|
|
|
"matrix.call.stats.connection.transport.1.isFocus": true,
|
|
|
|
"matrix.call.stats.connection.transport.1.localCandidateType": "srfx",
|
|
|
|
"matrix.call.stats.connection.transport.1.remoteCandidateType": "srfx",
|
|
|
|
"matrix.call.stats.connection.transport.1.networkType": "ethernet",
|
|
|
|
"matrix.call.stats.connection.transport.1.rtt": "null",
|
|
|
|
"matrix.call.stats.connection.audioConcealment.REMOTE_AUDIO_TRACK_ID.concealedAudio": 0,
|
|
|
|
"matrix.call.stats.connection.audioConcealment.REMOTE_AUDIO_TRACK_ID.totalAudioDuration": 0,
|
|
|
|
"matrix.call.stats.connection.audioConcealment.REMOTE_VIDEO_TRACK_ID.concealedAudio": 0,
|
|
|
|
"matrix.call.stats.connection.audioConcealment.REMOTE_VIDEO_TRACK_ID.totalAudioDuration": 0,
|
|
|
|
"matrix.call.stats.connection.totalAudioConcealment.concealedAudio": 0,
|
|
|
|
"matrix.call.stats.connection.totalAudioConcealment.totalAudioDuration": 0,
|
2023-04-05 16:25:26 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("on flattenByteSendStatsReportObject", () => {
|
2023-06-06 14:28:53 +08:00
|
|
|
const byteSentStatsReport = new Map<
|
|
|
|
string,
|
|
|
|
number
|
|
|
|
>() as ByteSentStatsReport;
|
|
|
|
byteSentStatsReport.callId = "callId";
|
|
|
|
byteSentStatsReport.opponentMemberId = "opponentMemberId";
|
|
|
|
byteSentStatsReport.set("4aa92608-04c6-428e-8312-93e17602a959", 132093);
|
|
|
|
byteSentStatsReport.set("a08e4237-ee30-4015-a932-b676aec894b1", 913448);
|
|
|
|
|
2023-04-05 16:25:26 +08:00
|
|
|
it("should flatten a Report to otel Attributes Object", () => {
|
|
|
|
expect(
|
2023-06-06 14:28:53 +08:00
|
|
|
ObjectFlattener.flattenReportObject(
|
|
|
|
"matrix.call.stats.bytesSend",
|
|
|
|
byteSentStatsReport
|
|
|
|
)
|
2023-04-05 16:25:26 +08:00
|
|
|
).toEqual({
|
2023-06-06 14:28:53 +08:00
|
|
|
"matrix.call.stats.bytesSend.4aa92608-04c6-428e-8312-93e17602a959": 132093,
|
|
|
|
"matrix.call.stats.bytesSend.a08e4237-ee30-4015-a932-b676aec894b1": 913448,
|
2023-04-05 16:25:26 +08:00
|
|
|
});
|
2023-06-06 14:28:53 +08:00
|
|
|
expect(byteSentStatsReport.callId).toEqual("callId");
|
|
|
|
expect(byteSentStatsReport.opponentMemberId).toEqual("opponentMemberId");
|
2023-04-05 16:25:26 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|