Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: chrome/test/data/webrtc/peerconnection_getstats.js

Issue 2489673003: RTCPeerConnection.getStats: Whitelist of stats in unittest. (Closed)
Patch Set: Addressed nits Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/media/webrtc/webrtc_browsertest_base.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /** 1 /**
2 * Copyright 2016 The Chromium Authors. All rights reserved. 2 * Copyright 2016 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /**
8 * Maps "RTCStats.type" values to descriptions of whitelisted (allowed to be
9 * exposed to the web) RTCStats-derived dictionaries described below.
10 * @private
11 */
12 var gStatsWhitelist = new Map();
13
14 /**
15 * RTCRTPStreamStats
16 * https://w3c.github.io/webrtc-stats/#streamstats-dict*
17 * @private
18 */
19 var kRTCRTPStreamStats = new RTCStats_(null, {
20 ssrc: 'string',
21 associateStatsId: 'string',
22 isRemote: 'boolean',
23 mediaType: 'string',
24 mediaTrackId: 'string',
25 transportId: 'string',
26 codecId: 'string',
27 firCount: 'number',
28 pliCount: 'number',
29 nackCount: 'number',
30 sliCount: 'number',
31 });
32
33 /*
34 * RTCCodecStats
35 * https://w3c.github.io/webrtc-stats/#codec-dict*
36 * @private
37 */
38 var kRTCCodecStats = new RTCStats_(null, {
39 payloadType: 'number',
40 codec: 'string',
41 clockRate: 'number',
42 channels: 'number',
43 parameters: 'string',
44 implementation: 'string',
45 });
46 gStatsWhitelist.set('codec', kRTCCodecStats);
47
48 /*
49 * RTCInboundRTPStreamStats
50 * https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
51 * @private
52 */
53 var kRTCInboundRTPStreamStats = new RTCStats_(kRTCRTPStreamStats, {
54 packetsReceived: 'number',
55 bytesReceived: 'number',
56 packetsLost: 'number',
57 jitter: 'number',
58 fractionLost: 'number',
59 packetsDiscarded: 'number',
60 packetsRepaired: 'number',
61 burstPacketsLost: 'number',
62 burstPacketsDiscarded: 'number',
63 burstLossCount: 'number',
64 burstDiscardCount: 'number',
65 burstLossRate: 'number',
66 burstDiscardRate: 'number',
67 gapLossRate: 'number',
68 gapDiscardRate: 'number',
69 });
70 gStatsWhitelist.set('inbound-rtp', kRTCInboundRTPStreamStats);
71
72 /*
73 * RTCOutboundRTPStreamStats
74 * https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*
75 * @private
76 */
77 var kRTCOutboundRTPStreamStats = new RTCStats_(kRTCRTPStreamStats, {
78 packetsSent: 'number',
79 bytesSent: 'number',
80 targetBitrate: 'number',
81 roundTripTime: 'number',
82 });
83 gStatsWhitelist.set('outbound-rtp', kRTCOutboundRTPStreamStats);
84
85 /*
86 * RTCPeerConnectionStats
87 * https://w3c.github.io/webrtc-stats/#pcstats-dict*
88 * @private
89 */
90 var kRTCPeerConnectionStats = new RTCStats_(null, {
91 dataChannelsOpened: 'number',
92 dataChannelsClosed: 'number',
93 });
94 gStatsWhitelist.set('peer-connection', kRTCPeerConnectionStats);
95
96 /*
97 * RTCMediaStreamStats
98 * https://w3c.github.io/webrtc-stats/#msstats-dict*
99 * @private
100 */
101 var kRTCMediaStreamStats = new RTCStats_(null, {
102 streamIdentifier: 'string',
103 trackIds: 'sequence_string',
104 });
105 gStatsWhitelist.set('stream', kRTCMediaStreamStats);
106
107 /*
108 * RTCMediaStreamTrackStats
109 * https://w3c.github.io/webrtc-stats/#mststats-dict*
110 * @private
111 */
112 var kRTCMediaStreamTrackStats = new RTCStats_(null, {
113 trackIdentifier: 'string',
114 remoteSource: 'boolean',
115 ended: 'boolean',
116 detached: 'boolean',
117 ssrcIds: 'sequence_string',
118 frameWidth: 'number',
119 frameHeight: 'number',
120 framesPerSecond: 'number',
121 framesSent: 'number',
122 framesReceived: 'number',
123 framesDecoded: 'number',
124 framesDropped: 'number',
125 framesCorrupted: 'number',
126 partialFramesLost: 'number',
127 fullFramesLost: 'number',
128 audioLevel: 'number',
129 echoReturnLoss: 'number',
130 echoReturnLossEnhancement: 'number',
131 });
132 gStatsWhitelist.set('track', kRTCMediaStreamTrackStats);
133
134 /*
135 * RTCDataChannelStats
136 * https://w3c.github.io/webrtc-stats/#dcstats-dict*
137 * @private
138 */
139 var kRTCDataChannelStats = new RTCStats_(null, {
140 label: 'string',
141 protocol: 'string',
142 datachannelid: 'number',
143 state: 'string',
144 messagesSent: 'number',
145 bytesSent: 'number',
146 messagesReceived: 'number',
147 bytesReceived: 'number',
148 });
149 gStatsWhitelist.set('data-channel', kRTCDataChannelStats);
150
151 /*
152 * RTCTransportStats
153 * https://w3c.github.io/webrtc-stats/#transportstats-dict*
154 * @private
155 */
156 var kRTCTransportStats = new RTCStats_(null, {
157 bytesSent: 'number',
158 bytesReceived: 'number',
159 rtcpTransportStatsId: 'string',
160 activeConnection: 'boolean',
161 selectedCandidatePairId: 'string',
162 localCertificateId: 'string',
163 remoteCertificateId: 'string',
164 });
165 gStatsWhitelist.set('transport', kRTCTransportStats);
166
167 /*
168 * RTCIceCandidateStats
169 * https://w3c.github.io/webrtc-stats/#icecandidate-dict*
170 * @private
171 */
172 var kRTCIceCandidateStats = new RTCStats_(null, {
173 ip: 'string',
174 port: 'number',
175 protocol: 'string',
176 candidateType: 'string',
177 priority: 'number',
178 url: 'string',
179 });
180 gStatsWhitelist.set('local-candidate', kRTCIceCandidateStats);
181 gStatsWhitelist.set('remote-candidate', kRTCIceCandidateStats);
182
183 /*
184 * RTCIceCandidatePairStats
185 * https://w3c.github.io/webrtc-stats/#candidatepair-dict*
186 * @private
187 */
188 var kRTCIceCandidatePairStats = new RTCStats_(null, {
189 transportId: 'string',
190 localCandidateId: 'string',
191 remoteCandidateId: 'string',
192 state: 'string',
193 priority: 'number',
194 nominated: 'boolean',
195 writable: 'boolean',
196 readable: 'boolean',
197 bytesSent: 'number',
198 bytesReceived: 'number',
199 totalRtt: 'number',
200 currentRtt: 'number',
201 availableOutgoingBitrate: 'number',
202 availableIncomingBitrate: 'number',
203 requestsReceived: 'number',
204 requestsSent: 'number',
205 responsesReceived: 'number',
206 responsesSent: 'number',
207 retransmissionsReceived: 'number',
208 retransmissionsSent: 'number',
209 consentRequestsReceived: 'number',
210 consentRequestsSent: 'number',
211 consentResponsesReceived: 'number',
212 consentResponsesSent: 'number',
213 });
214 gStatsWhitelist.set('candidate-pair', kRTCIceCandidatePairStats);
215
216 /*
217 * RTCCertificateStats
218 * https://w3c.github.io/webrtc-stats/#certificatestats-dict*
219 * @private
220 */
221 var kRTCCertificateStats = new RTCStats_(null, {
222 fingerprint: 'string',
223 fingerprintAlgorithm: 'string',
224 base64Certificate: 'string',
225 issuerCertificateId: 'string',
226 });
227 gStatsWhitelist.set('certificate', kRTCCertificateStats);
228
7 // Public interface to tests. These are expected to be called with 229 // Public interface to tests. These are expected to be called with
8 // ExecuteJavascript invocations from the browser tests and will return answers 230 // ExecuteJavascript invocations from the browser tests and will return answers
9 // through the DOM automation controller. 231 // through the DOM automation controller.
10 232
11 /** 233 /**
12 * Verifies that the promise-based |RTCPeerConnection.getStats| returns stats. 234 * Verifies that the promise-based |RTCPeerConnection.getStats| returns stats,
235 * makes sure that all returned stats have the base RTCStats-members and that
236 * all stats are allowed by the whitelist.
13 * 237 *
14 * Returns ok-got-stats on success. 238 * Returns "ok-" followed by JSON-stringified array of "RTCStats.type" values
239 * to the test, these being the different types of stats that was returned by
240 * this call to getStats.
15 */ 241 */
16 function verifyStatsGeneratedPromise() { 242 function verifyStatsGeneratedPromise() {
17 peerConnection_().getStats() 243 peerConnection_().getStats()
18 .then(function(report) { 244 .then(function(report) {
19 if (report == null || report.size == 0) 245 if (report == null || report.size == 0)
20 throw new failTest('report is null or empty.'); 246 throw new failTest('report is null or empty.');
21 // Sanity check that applies to all stats. 247 let statsTypes = new Set();
22 var ids = new Set(); 248 let ids = new Set();
23 report.forEach(function(stats) { 249 for (let stats of report.values()) {
24 if (typeof(stats.id) !== 'string') 250 verifyStatsIsWhitelisted_(stats);
25 throw failTest('stats.id is not a string.'); 251 statsTypes.add(stats.type);
26 if (ids.has(stats.id)) 252 if (ids.has(stats.id))
27 throw failTest('stats.id is not a unique identifier.'); 253 throw failTest('stats.id is not a unique identifier.');
28 ids.add(stats.id); 254 ids.add(stats.id);
29 if (typeof(stats.timestamp) !== 'number' || stats.timestamp <= 0) 255 }
30 throw failTest('stats.timestamp is not a positive number.'); 256 returnToTest('ok-' + JSON.stringify(Array.from(statsTypes.values())));
31 if (typeof(stats.type) !== 'string')
32 throw failTest('stats.type is not a string.');
33 });
34 // TODO(hbos): When the new stats collection API is more mature (and
35 // certainly before unflagging the new stats API) add a whitelist of
36 // allowed stats to prevent accidentally exposing stats to the web that
37 // are not in the spec and that verifies type information. Status at
38 // crbug.com/627816. Stats collection is tested in the WebRTC repo and
39 // automatically surfaced to Blink, but there should be a process of
40 // having to land a Blink CL in order to expose a new RTCStats dictionary.
41 returnToTest('ok-got-stats');
42 }, 257 },
43 function(e) { 258 function(e) {
44 throw failTest('Promise was rejected: ' + e); 259 throw failTest('Promise was rejected: ' + e);
45 }); 260 });
46 } 261 }
262
263 /**
264 * Returns a complete list of whitelisted "RTCStats.type" values as a
265 * JSON-stringified array of strings to the test.
266 */
267 function getWhitelistedStatsTypes() {
268 returnToTest(JSON.stringify(Array.from(gStatsWhitelist.keys())));
269 }
270
271 // Internals.
272
273 /** @private */
274 function RTCStats_(parent, membersObject) {
275 if (parent != null)
276 Object.assign(this, parent);
277 Object.assign(this, membersObject);
278 }
279
280 /**
281 * Checks if |stats| correctly maps to a a whitelisted RTCStats-derived
282 * dictionary, throwing |failTest| if it doesn't. See |gStatsWhitelist|.
283 *
284 * The "RTCStats.type" must map to a known dictionary description. Every member
285 * is optional, but if present it must be present in the whitelisted dictionary
286 * description and its type must match.
287 * @private
288 */
289 function verifyStatsIsWhitelisted_(stats) {
290 if (stats == null)
291 throw failTest('stats is null or undefined: ' + stats);
292 if (typeof(stats.id) !== 'string')
293 throw failTest('stats.id is not a string:' + stats.id);
294 if (typeof(stats.timestamp) !== 'number' || !isFinite(stats.timestamp) ||
295 stats.timestamp <= 0) {
296 throw failTest('stats.timestamp is not a positive finite number: ' +
297 stats.timestamp);
298 }
299 if (typeof(stats.type) !== 'string')
300 throw failTest('stats.type is not a string: ' + stats.type);
301 let whitelistedStats = gStatsWhitelist.get(stats.type);
302 if (whitelistedStats == null)
303 throw failTest('stats.type is not a whitelisted type: ' + stats.type);
304 for (let propertyName in stats) {
305 if (propertyName === 'id' || propertyName === 'timestamp' ||
306 propertyName === 'type') {
307 continue;
308 }
309 if (!whitelistedStats.hasOwnProperty(propertyName)) {
310 throw failTest('stats.' + propertyName + ' is not a whitelisted ' +
311 'member: ' + stats[propertyName]);
312 }
313 if (!whitelistedStats[propertyName].startsWith('sequence_')) {
314 if (typeof(stats[propertyName]) !== whitelistedStats[propertyName]) {
315 throw failTest('stats.' + propertyName + ' should have a different ' +
316 'type according to the whitelist: ' + stats[propertyName] + ' vs ' +
317 whitelistedStats[propertyName]);
318 }
319 } else {
320 if (!Array.isArray(stats[propertyName])) {
321 throw failTest('stats.' + propertyName + ' should have a different ' +
322 'type according to the whitelist (should be an array): ' +
323 JSON.stringify(stats[propertyName]) + ' vs ' +
324 whitelistedStats[propertyName]);
325 }
326 let elementType = whitelistedStats[propertyName].substring(9);
327 for (let element in stats[propertyName]) {
328 if (typeof(element) !== elementType) {
329 throw failTest('stats.' + propertyName + ' should have a different ' +
330 'type according to the whitelist (an element of the array has ' +
331 'the incorrect type): ' + JSON.stringify(stats[propertyName]) +
332 ' vs ' + whitelistedStats[propertyName]);
333 }
334 }
335 }
336 }
337 }
OLDNEW
« no previous file with comments | « chrome/browser/media/webrtc/webrtc_browsertest_base.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698