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

Side by Side Diff: tracing/tracing/extras/chrome/cpu_time_test.html

Issue 2807243002: Construct Cpu Time MultidimensionalView (Closed)
Patch Set: Created 3 years, 8 months 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
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright 2017 The Chromium Authors. All rights reserved. 3 Copyright 2017 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be 4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file. 5 found in the LICENSE file.
6 --> 6 -->
7 7
8 <link rel="import" href="/tracing/core/test_utils.html"> 8 <link rel="import" href="/tracing/core/test_utils.html">
9 <link rel="import" href="/tracing/extras/chrome/cpu_time.html"> 9 <link rel="import" href="/tracing/extras/chrome/cpu_time.html">
10 <link rel="import" href="/tracing/extras/chrome/cpu_time_test_utils.html">
10 11
11 <script> 12 <script>
12 'use strict'; 13 'use strict';
13 14
14 tr.b.unittest.testSuite(function() { 15 tr.b.unittest.testSuite(function() {
15 const getStageToInitiatorToSegmentBounds = 16 const getStageToInitiatorToSegmentBounds =
16 tr.e.chrome.cpuTime.getStageToInitiatorToSegmentBounds; 17 tr.e.chrome.cpuTime.getStageToInitiatorToSegmentBounds;
17 18
18 const INITIATOR_TYPE = tr.model.um.INITIATOR_TYPE; 19 const INITIATOR_TYPE = tr.model.um.INITIATOR_TYPE;
19 20
21 const CHROME_PROCESS_NAMES =
22 tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES;
23
24 const constructMultiDimensionalView =
25 tr.e.chrome.cpuTime.constructMultiDimensionalView;
26
27 const buildModelFromSpec = tr.e.chrome.cpuTimeTestUtils.buildModelFromSpec;
28
20 test('getCpuTimeForThread', () => { 29 test('getCpuTimeForThread', () => {
21 const model = tr.c.TestUtils.newModel(function(model) { 30 const model = tr.c.TestUtils.newModel(function(model) {
22 const thread = model.getOrCreateProcess(1).getOrCreateThread(1); 31 const thread = model.getOrCreateProcess(1).getOrCreateThread(1);
23 const sliceSpecs = [ 32 const sliceSpecs = [
24 {wallTimeBounds: [100, 200], cpuStart: 120, cpuDuration: 50}, 33 {wallTimeBounds: [100, 200], cpuStart: 120, cpuDuration: 50},
25 {wallTimeBounds: [300, 600], cpuStart: 350, cpuDuration: 150} 34 {wallTimeBounds: [300, 600], cpuStart: 350, cpuDuration: 150}
26 ]; 35 ];
27 for (const sliceSpec of sliceSpecs) { 36 for (const sliceSpec of sliceSpecs) {
28 thread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({ 37 thread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
29 type: tr.model.ThreadSlice, 38 type: tr.model.ThreadSlice,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 const map = getStageToInitiatorToSegmentBounds( 78 const map = getStageToInitiatorToSegmentBounds(
70 model.userModel.segments, model.bounds); 79 model.userModel.segments, model.bounds);
71 80
72 // Ignoring Idle Expectations, we have the following segments: 81 // Ignoring Idle Expectations, we have the following segments:
73 // [100, 300]: CSS Animation 82 // [100, 300]: CSS Animation
74 // [300, 400]: CSS Animation, Video Animation 83 // [300, 400]: CSS Animation, Video Animation
75 // [400, 600]: Scroll Response 84 // [400, 600]: Scroll Response
76 const allSegments = map.get('all_stages').get('all_initiators'); 85 const allSegments = map.get('all_stages').get('all_initiators');
77 assert.sameDeepMembers( 86 assert.sameDeepMembers(
78 allSegments.map(s => [s.min, s.max]), 87 allSegments.map(s => [s.min, s.max]),
79 [[100, 300], [300, 400], [400, 600]]); 88 [[100, 300], [300, 400], [400, 600]]
89 );
80 90
81 const videoAnimationSegments = 91 const videoAnimationSegments =
82 map.get('Animation').get(INITIATOR_TYPE.VIDEO); 92 map.get('Animation').get(INITIATOR_TYPE.VIDEO);
83 assert.sameDeepMembers( 93 assert.sameDeepMembers(
84 videoAnimationSegments.map(s => [s.min, s.max]), 94 videoAnimationSegments.map(s => [s.min, s.max]),
85 [[300, 400]]); 95 [[300, 400]]);
86 96
87 const cssAnimationSegments = 97 const cssAnimationSegments =
88 map.get('Animation').get(INITIATOR_TYPE.CSS); 98 map.get('Animation').get(INITIATOR_TYPE.CSS);
89 assert.sameDeepMembers( 99 assert.sameDeepMembers(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 140
131 const map = getStageToInitiatorToSegmentBounds(model.userModel.segments, 141 const map = getStageToInitiatorToSegmentBounds(model.userModel.segments,
132 tr.b.math.Range.fromExplicitRange(150, 350)); 142 tr.b.math.Range.fromExplicitRange(150, 350));
133 143
134 // Ignoring Idle Expectations, we have the following segments in range: 144 // Ignoring Idle Expectations, we have the following segments in range:
135 // [150, 300]: CSS Animation 145 // [150, 300]: CSS Animation
136 // [300, 350]: CSS Animation, Video Animation 146 // [300, 350]: CSS Animation, Video Animation
137 const allSegments = map.get('all_stages').get('all_initiators'); 147 const allSegments = map.get('all_stages').get('all_initiators');
138 assert.sameDeepMembers( 148 assert.sameDeepMembers(
139 allSegments.map(s => [s.min, s.max]), 149 allSegments.map(s => [s.min, s.max]),
140 [[150, 300], [300, 350]]); 150 [[150, 300], [300, 350]]
151 );
141 152
142 const videoAnimationSegments = 153 const videoAnimationSegments =
143 map.get('Animation').get(INITIATOR_TYPE.VIDEO); 154 map.get('Animation').get(INITIATOR_TYPE.VIDEO);
144 assert.sameDeepMembers( 155 assert.sameDeepMembers(
145 videoAnimationSegments.map(s => [s.min, s.max]), 156 videoAnimationSegments.map(s => [s.min, s.max]),
146 [[300, 350]]); 157 [[300, 350]]);
147 158
148 const cssAnimationSegments = 159 const cssAnimationSegments =
149 map.get('Animation').get(INITIATOR_TYPE.CSS); 160 map.get('Animation').get(INITIATOR_TYPE.CSS);
150 assert.sameDeepMembers( 161 assert.sameDeepMembers(
151 cssAnimationSegments.map(s => [s.min, s.max]), 162 cssAnimationSegments.map(s => [s.min, s.max]),
152 [[150, 300], [300, 350]]); 163 [[150, 300], [300, 350]]);
153 164
154 const allAnimationSegments = 165 const allAnimationSegments =
155 map.get('Animation').get('all_initiators'); 166 map.get('Animation').get('all_initiators');
156 assert.sameDeepMembers( 167 assert.sameDeepMembers(
157 allAnimationSegments.map(s => [s.min, s.max]), 168 allAnimationSegments.map(s => [s.min, s.max]),
158 [[150, 300], [300, 350]]); 169 [[150, 300], [300, 350]]);
159 170
160 // There should be no Response segments 171 // There should be no Response segments
161 assert.isFalse(map.has('Response')); 172 assert.isFalse(map.has('Response'));
162 }); 173 });
174
175 /**
176 * Given the root node of a top down multidimensional tree view, and returns
tdresser 2017/04/10 20:48:29 and returns -> returns
dproy 2017/05/11 00:50:46 Done.
177 * the node at |path|.
178 */
179 function getNodeValues_(root, path) {
180 let node = root;
181 for (let i = 0; i <= 2; i++) {
tdresser 2017/04/10 20:48:29 Why 2? (Maybe deserves a comment?)
dproy 2017/05/11 00:50:46 Changed to path.length.
182 for (const component of path[i]) {
183 node = node.children[i].get(component);
184 }
185 }
186 return node.values;
187 }
188
189 const getCpuUsage_ = nodeValues => nodeValues[0].total;
190 const getCpuTotal_ = nodeValues => nodeValues[1].total;
191
192 /**
193 * Returns a simple model spec with one process (browser process) and one
194 * thread (CrBrowserMain).
195 *
196 * It does not contain any slices or expectations - those should be added
197 * manually.
198 *
199 * This is a function instead of just a variable because the test functions
200 * are meant to modify this modelSpec and insert suitable expectations.
201 */
202 function getSimpleModelSpec_() {
203 return {
204 processes: [
205 {
206 name: 'Browser',
207 pid: 12345,
208 threads: [
209 {
210 name: 'CrBrowserMain',
211 tid: 1,
212 slices: []
213 },
214 ],
215 },
216 ],
217 expectations: [],
218 };
219 }
220
221 test('constructMultiDimensionalView_' +
222 'slicesDoNotStraddleExpecationBoundaries', () => {
223 const simpleModelSpec = getSimpleModelSpec_();
224 simpleModelSpec.processes[0].threads[0].slices.push(
225 {range: [150, 200], cpu: 30},
226 {range: [205, 255], cpu: 20}
227 );
228 simpleModelSpec.expectations.push(
229 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS, range: [100, 300]}
230 );
231
232 const path = [
233 [CHROME_PROCESS_NAMES.BROWSER],
234 ['CrBrowserMain'], ['Animation', 'CSS']];
235
236 const model = buildModelFromSpec(simpleModelSpec);
237 const root = constructMultiDimensionalView(model, model.bounds);
238 const values = getNodeValues_(root, path);
239
240 assert.closeTo(getCpuUsage_(values), (30 + 20) / 200, 1e-7);
tdresser 2017/04/10 20:48:29 It might be worth adding comments indicating where
dproy 2017/05/11 00:50:46 I added a few comments about the calculations, esp
241 assert.closeTo(getCpuTotal_(values), (30 + 20), 1e-7);
242 });
243
244 test('constructMultiDimensionalView_' +
245 'slicesStraddleExpectationBoundaries', () => {
246 const simpleModelSpec = getSimpleModelSpec_();
247 simpleModelSpec.processes[0].threads[0].slices.push(
248 {range: [150, 200], cpu: 30},
249 {range: [205, 255], cpu: 20}
250 );
251 simpleModelSpec.expectations.push(
252 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
253 range: [75, 175]}
254 );
255 const path = [
256 [CHROME_PROCESS_NAMES.BROWSER],
257 ['CrBrowserMain'], ['Animation', 'Video']
258 ];
259
260 const model = buildModelFromSpec(simpleModelSpec);
261 const root = constructMultiDimensionalView(model, model.bounds);
262 const values = getNodeValues_(root, path);
263
264 assert.closeTo(getCpuUsage_(values), 15 / 100, 1e-7);
265 assert.closeTo(getCpuTotal_(values), 15, 1e-7);
266 });
267
268 test('constructMultiDimensionalView_' +
269 'singleThread-disjointExpectationsOfSameInitiator', () => {
270 const simpleModelSpec = getSimpleModelSpec_();
271 simpleModelSpec.processes[0].threads[0].slices.push(
272 {range: [150, 200], cpu: 30},
273 {range: [205, 255], cpu: 20}
274 );
275 simpleModelSpec.expectations.push(
276 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
277 range: [100, 160]},
278 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
279 range: [205, 225]}
280 );
281 const path = [
282 [CHROME_PROCESS_NAMES.BROWSER],
283 ['CrBrowserMain'], ['Response', 'Scroll']
284 ];
285
286 const model = buildModelFromSpec(simpleModelSpec);
287 const root = constructMultiDimensionalView(model, model.bounds);
288 const values = getNodeValues_(root, path);
289
290 assert.closeTo(getCpuUsage_(values),
291 (0.2 * 30 + 0.4 * 20) / (60 + 20), 1e-7);
292 assert.closeTo(getCpuTotal_(values),
293 0.2 * 30 + 0.4 * 20, 1e-7);
294 });
295
296 test('constructMultiDimensionalView_' +
297 'singleThread-overlappingExpectationsOfSameInitiators', () => {
298 const simpleModelSpec = getSimpleModelSpec_();
299 simpleModelSpec.processes[0].threads[0].slices.push(
300 {range: [150, 200], cpu: 30},
301 {range: [205, 255], cpu: 20}
302 );
303 simpleModelSpec.expectations.push(
304 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
305 range: [100, 190]},
306 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
307 range: [160, 230]}
308 );
309 const path = [
310 [CHROME_PROCESS_NAMES.BROWSER],
311 ['CrBrowserMain'], ['Animation', 'CSS']
312 ];
313
314 const model = buildModelFromSpec(simpleModelSpec);
315 const root = constructMultiDimensionalView(model, model.bounds);
316 const values = getNodeValues_(root, path);
317
318 assert.closeTo(getCpuUsage_(values), (30 + 0.5 * 20) / 130, 1e-7);
319 assert.closeTo(getCpuTotal_(values), 30 + 0.5 * 20, 1e-7);
320 });
321
322 test('constructMultiDimensionalView_' +
323 'singleThread-overlappingExpectationsOfDifferentInitiators', () => {
324 const simpleModelSpec = getSimpleModelSpec_();
325 simpleModelSpec.processes[0].threads[0].slices.push(
326 {range: [150, 200], cpu: 30},
327 {range: [205, 255], cpu: 20}
328 );
329 simpleModelSpec.expectations.push(
330 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
331 range: [100, 190]},
332 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
333 range: [160, 230]}
334 );
335 const path = [
336 [CHROME_PROCESS_NAMES.BROWSER],
337 ['CrBrowserMain'], ['Animation', 'all_initiators']
338 ];
339
340 const model = buildModelFromSpec(simpleModelSpec);
341 const root = constructMultiDimensionalView(model, model.bounds);
342 const values = getNodeValues_(root, path);
343
344 assert.closeTo(getCpuUsage_(values),
345 (30 + 0.5 * 20) / 130, 1e-7);
346 assert.closeTo(getCpuTotal_(values),
347 30 + 0.5 * 20, 1e-7);
348 });
349
350 test('constructMultiDimensionalView_' +
351 'singleThread-allStages-customRangeOfInterest', () => {
352 const simpleModelSpec = getSimpleModelSpec_();
353 simpleModelSpec.processes[0].threads[0].slices.push(
354 {range: [150, 200], cpu: 30},
355 {range: [205, 255], cpu: 20}
356 );
357 simpleModelSpec.expectations.push(
358 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
359 range: [100, 190]},
360 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
361 range: [160, 230]}
362 );
363 const path = [
364 [CHROME_PROCESS_NAMES.BROWSER],
365 ['CrBrowserMain'], ['all_stages', 'all_initiators']
366 ];
367
368 const model = buildModelFromSpec(simpleModelSpec);
369 const rangeOfInterest = new tr.b.math.Range.fromExplicitRange(100, 210);
370 const root = constructMultiDimensionalView(model, rangeOfInterest);
371 const values = getNodeValues_(root, path);
372
373 assert.closeTo(getCpuUsage_(values), (30 + 0.1 * 20) / 110, 1e-7);
374 assert.closeTo(getCpuTotal_(values), 30 + 0.1 * 20, 1e-7);
375 });
376
377 /**
378 * Returns a model spec where the browser process has two worker threads.
379 *
380 * This is a function instead of just a variable because the test functions
381 * are meant to modify this modelSpec and insert suitable expectations.
382 */
383 function getMultipleThreadsOfSameTypeModelSpec_() {
384 return {
385 processes: [
386 {
387 name: 'Browser',
388 pid: 12345,
389 threads: [
390 {
391 name: 'CrBrowserMain',
392 tid: 1,
393 slices: [],
394 },
395 {
396 name: 'Worker/1',
397 tid: 42,
398 slices: (() => {
399 const slices = [];
400 for (let i = 0; i < 1000; i += 20) {
401 slices.push({range: [i, i + 10], cpu: 5});
402 }
403 return slices;
404 })(),
405 },
406 {
407 name: 'Worker/2',
408 tid: 52,
409 slices: (() => {
410 const slices = [];
411 for (let i = 0; i < 1000; i += 100) {
412 slices.push({range: [i, i + 80], cpu: 40});
413 }
414 return slices;
415 })(),
416 },
417 ],
418 },
419 ],
420
421 expectations: [],
422 };
423 }
424
425 test('constructMultiDimensionalView_multipleThreadsOfSameType_' +
426 'singleExpectation', () => {
427 const modelSpec = getMultipleThreadsOfSameTypeModelSpec_();
428 modelSpec.expectations.push(
429 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
430 range: [0, 90]}
431 );
432
433 const path = [
434 [CHROME_PROCESS_NAMES.BROWSER],
435 ['Worker'], ['Animation', 'Video']
436 ];
437
438 const model = buildModelFromSpec(modelSpec);
439 const root = constructMultiDimensionalView(model, model.bounds);
440 const values = getNodeValues_(root, path);
441
442 assert.closeTo(getCpuUsage_(values), (5 * 5 + 40) / 90, 1e-7);
443 assert.closeTo(getCpuTotal_(values), 5 * 5 + 40, 1e-7);
444 });
445
446 test('constructMultiDimensionalView_multipleThreadsOfSameType_' +
447 'disjointExpectationSameInitiator', () => {
448 const modelSpec = getMultipleThreadsOfSameTypeModelSpec_();
449 modelSpec.expectations.push(
450 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
451 range: [500, 560]},
452 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
453 range: [690, 890]}
454 );
455
456 const path = [
457 [CHROME_PROCESS_NAMES.BROWSER],
458 ['Worker'], ['Animation', 'CSS']
459 ];
460
461 const model = buildModelFromSpec(modelSpec);
462 const root = constructMultiDimensionalView(model, model.bounds);
463 const values = getNodeValues_(root, path);
464
465 assert.closeTo(getCpuUsage_(values),
466 ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)) / (60 + 200), 1e-7);
467 assert.closeTo(getCpuTotal_(values),
468 (5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2), 1e-7);
469 });
470
471 test('constructMultiDimensionalView_multipleThreadsOfSameType_' +
472 'overlappingExpectationsOfSameInitiator', () => {
473 const modelSpec = getMultipleThreadsOfSameTypeModelSpec_();
474 // [Scroll R]
475 // [Scroll R]
476 modelSpec.expectations.push(
477 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
478 range: [210, 260]},
479 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
480 range: [250, 300]}
481 );
482
483 const path = [
484 [CHROME_PROCESS_NAMES.BROWSER],
485 ['Worker'], ['Response', 'Scroll']
486 ];
487
488 const model = buildModelFromSpec(modelSpec);
489 const root = constructMultiDimensionalView(model, model.bounds);
490 const values = getNodeValues_(root, path);
491
492 assert.closeTo(getCpuUsage_(values),
493 (5 * 4 + 40 * (70 / 80)) / 90, 1e-7);
494 assert.closeTo(getCpuTotal_(values),
495 5 * 4 + 40 * (70 / 80), 1e-7);
496 });
497
498 test('constructMultiDimensionalView_multipleThreadsOfSameType_' +
499 'disjointExpectationsAllInitiators', () => {
500 const modelSpec = getMultipleThreadsOfSameTypeModelSpec_();
501 modelSpec.expectations.push(
502 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
503 range: [0, 90]},
504 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
505 range: [500, 560]},
506 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
507 range: [690, 890]}
508 );
509
510 const path = [
511 [CHROME_PROCESS_NAMES.BROWSER],
512 ['Worker'], ['Animation', 'all_initiators']
513 ];
514
515 const model = buildModelFromSpec(modelSpec);
516 const root = constructMultiDimensionalView(model, model.bounds);
517 const values = getNodeValues_(root, path);
518
519 assert.closeTo(getCpuUsage_(values),
520 ((5 * 5 + 40) + ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2))) /
521 (90 + 60 + 200), 1e-7);
522 assert.closeTo(getCpuTotal_(values),
523 (5 * 5 + 40) + ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)),
524 1e-7);
525 });
526
527
528 test('constructMultiDimensionalView_multipleThreadsOfSameType_' +
529 'overlappingExpectationsAllInitiators', () => {
530 const modelSpec = getMultipleThreadsOfSameTypeModelSpec_();
531 // [Click R]
532 // [Scroll R]
533 // [Scroll R]
534 modelSpec.expectations.push(
535 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
536 range: [200, 220]},
537 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
538 range: [210, 260]},
539 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
540 range: [250, 300]}
541 );
542
543 const path = [
544 [CHROME_PROCESS_NAMES.BROWSER],
545 ['Worker'], ['Response', 'all_initiators']
546 ];
547
548 const model = buildModelFromSpec(modelSpec);
549 const root = constructMultiDimensionalView(model, model.bounds);
550 const values = getNodeValues_(root, path);
551
552 assert.closeTo(getCpuUsage_(values),
553 (5 * 5 + 40) / 100, 1e-7);
554 assert.closeTo(getCpuTotal_(values),
555 5 * 5 + 40, 1e-7);
556 });
557
558
559 test('constructMultiDimensionalView_multipleThreadsOfSameType_' +
560 'allStagesAllInitiators', () => {
561 const modelSpec = getMultipleThreadsOfSameTypeModelSpec_();
562 // [Video A] [Click R] [CSS A] [ CSS A ]
563 // [Scroll R]
564 // [Scroll R]
565 modelSpec.expectations.push(
566 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
567 range: [0, 90]},
568 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
569 range: [200, 220]},
570 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
571 range: [210, 260]},
572 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
573 range: [250, 300]},
574 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
575 range: [500, 560]},
576 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
577 range: [690, 890]}
578 );
579
580 const path = [
581 [CHROME_PROCESS_NAMES.BROWSER],
582 ['Worker'], ['all_stages', 'all_initiators']
583 ];
584
585 const model = buildModelFromSpec(modelSpec);
586 const root = constructMultiDimensionalView(model, model.bounds);
587 const values = getNodeValues_(root, path);
588
589 assert.closeTo(getCpuUsage_(values), (250 + 400) / 990, 1e-7);
590 assert.closeTo(getCpuTotal_(values), 250 + 400, 1e-7);
591 });
592
593 /**
594 * Returns a model spec where there are two renderer processes, each with a
595 * renderer main thread.
596 *
597 * This is a function instead of just a variable because the test functions
598 * are meant to modify this modelSpec and insert suitable expectations.
599 */
600 function getMultipleProcessesOfSameTypeModelSpec_() {
601 return {
602 processes: [
603 {
604 name: 'Browser',
605 pid: 12345,
606 threads: [
607 {
608 name: 'CrBrowserMain',
609 tid: 1,
610 slices: [],
611 },
612 ],
613 },
614 {
615 name: 'Renderer',
616 pid: 20001,
617 threads: [
618 {
619 name: 'CrRendererMain',
620 tid: 42,
621 slices: (() => {
622 const slices = [];
623 for (let i = 0; i < 1000; i += 20) {
624 slices.push({range: [i, i + 10], cpu: 5});
625 }
626 return slices;
627 })(),
628 },
629 ],
630 },
631 {
632 name: 'Renderer',
633 pid: 30001,
634 threads: [
635 {
636 name: 'CrRendererMain',
637 tid: 52,
638 slices: (() => {
639 const slices = [];
640 for (let i = 0; i < 1000; i += 100) {
641 slices.push({range: [i, i + 80], cpu: 40});
642 }
643 return slices;
644 })(),
645 },
646 ]
647 },
648 ],
649
650 expectations: [],
651 };
652 }
653
654 test('constructMultiDimensionalView_multipleProcessesOfSameType_' +
655 'singleExpectation', () => {
656 const modelSpec = getMultipleProcessesOfSameTypeModelSpec_();
657 modelSpec.expectations.push(
658 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
659 range: [0, 90]}
660 );
661
662 const path = [
663 [CHROME_PROCESS_NAMES.RENDERER],
664 ['CrRendererMain'], ['Animation', 'Video']
665 ];
666
667 const model = buildModelFromSpec(modelSpec);
668 const root = constructMultiDimensionalView(model, model.bounds);
669 const values = getNodeValues_(root, path);
670
671 assert.closeTo(getCpuUsage_(values), (5 * 5 + 40) / 90, 1e-7);
672 assert.closeTo(getCpuTotal_(values), 5 * 5 + 40, 1e-7);
673 });
674
675 test('constructMultiDimensionalView_multipleProcessesOfSameType_' +
676 'disjointExpectationSameInitiator', () => {
677 const modelSpec = getMultipleProcessesOfSameTypeModelSpec_();
678 modelSpec.expectations.push(
679 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
680 range: [500, 560]},
681 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
682 range: [690, 890]}
683 );
684
685 const path = [
686 [CHROME_PROCESS_NAMES.RENDERER],
687 ['CrRendererMain'], ['Animation', 'CSS']
688 ];
689
690 const model = buildModelFromSpec(modelSpec);
691 const root = constructMultiDimensionalView(model, model.bounds);
692 const values = getNodeValues_(root, path);
693
694 assert.closeTo(getCpuUsage_(values),
695 ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)) / (60 + 200), 1e-7);
696 assert.closeTo(getCpuTotal_(values),
697 (5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2), 1e-7);
698 });
699
700 test('constructMultiDimensionalView_multipleProcessesOfSameType_' +
701 'overlappingExpectationsOfSameInitiator', () => {
702 const modelSpec = getMultipleProcessesOfSameTypeModelSpec_();
703 // [Scroll R]
704 // [Scroll R]
705 modelSpec.expectations.push(
706 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
707 range: [210, 260]},
708 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
709 range: [250, 300]}
710 );
711
712 const path = [
713 [CHROME_PROCESS_NAMES.RENDERER],
714 ['CrRendererMain'], ['Response', 'Scroll']
715 ];
716
717 const model = buildModelFromSpec(modelSpec);
718 const root = constructMultiDimensionalView(model, model.bounds);
719 const values = getNodeValues_(root, path);
720
721 assert.closeTo(getCpuUsage_(values),
722 (5 * 4 + 40 * (70 / 80)) / 90, 1e-7);
723 assert.closeTo(getCpuTotal_(values),
724 5 * 4 + 40 * (70 / 80), 1e-7);
725 });
726
727 test('constructMultiDimensionalView_multipleProcessesOfSameType_' +
728 'disjointExpectationsAllInitiators', () => {
729 const modelSpec = getMultipleProcessesOfSameTypeModelSpec_();
730 modelSpec.expectations.push(
731 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
732 range: [0, 90]},
733 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
734 range: [500, 560]},
735 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
736 range: [690, 890]}
737 );
738
739 const path = [
740 [CHROME_PROCESS_NAMES.RENDERER],
741 ['CrRendererMain'], ['Animation', 'all_initiators']
742 ];
743
744 const model = buildModelFromSpec(modelSpec);
745 const root = constructMultiDimensionalView(model, model.bounds);
746 const values = getNodeValues_(root, path);
747
748 assert.closeTo(getCpuUsage_(values),
749 ((5 * 5 + 40) + ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2))) /
750 (90 + 60 + 200), 1e-7);
751 assert.closeTo(getCpuTotal_(values),
752 (5 * 5 + 40) + ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)),
753 1e-7);
754 });
755
756
757 test('constructMultiDimensionalView_multipleProcessesOfSameType_' +
758 'overlappingExpectationsAllInitiators', () => {
759 const modelSpec = getMultipleProcessesOfSameTypeModelSpec_();
760 // [Click R]
761 // [Scroll R]
762 // [Scroll R]
763 modelSpec.expectations.push(
764 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
765 range: [200, 220]},
766 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
767 range: [210, 260]},
768 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
769 range: [250, 300]}
770 );
771
772 const path = [
773 [CHROME_PROCESS_NAMES.RENDERER],
774 ['CrRendererMain'], ['Response', 'all_initiators']
775 ];
776
777 const model = buildModelFromSpec(modelSpec);
778 const root = constructMultiDimensionalView(model, model.bounds);
779 const values = getNodeValues_(root, path);
780
781 assert.closeTo(getCpuUsage_(values), (5 * 5 + 40) / 100, 1e-7);
782 assert.closeTo(getCpuTotal_(values), 5 * 5 + 40, 1e-7);
783 });
784
785
786 test('constructMultiDimensionalView_multipleProcessesOfSameType_' +
787 'allStagesAllInitiators', () => {
788 const modelSpec = getMultipleProcessesOfSameTypeModelSpec_();
789 // [Video A] [Click R] [CSS A] [ CSS A ]
790 // [Scroll R]
791 // [Scroll R]
792 modelSpec.expectations.push(
793 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
794 range: [0, 90]},
795 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
796 range: [200, 220]},
797 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
798 range: [210, 260]},
799 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
800 range: [250, 300]},
801 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
802 range: [500, 560]},
803 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
804 range: [690, 890]}
805 );
806
807 const path = [
808 [CHROME_PROCESS_NAMES.RENDERER],
809 ['CrRendererMain'], ['all_stages', 'all_initiators']
810 ];
811
812 const model = buildModelFromSpec(modelSpec);
813 const root = constructMultiDimensionalView(model, model.bounds);
814 const values = getNodeValues_(root, path);
815
816 assert.closeTo(getCpuUsage_(values), (250 + 400) / 990, 1e-7);
817 assert.closeTo(getCpuTotal_(values), 250 + 400, 1e-7);
818 });
819
820 /**
821 * Returns a model spec where the browser process has a main thread and an IO
822 * thread.
823 *
824 * This is a function instead of just a variable because the test functions
825 * are meant to modify this modelSpec and insert suitable expectations.
826 */
827 function getAllThreadsOfSameProcessModelSpec_() {
828 return {
829 processes: [
830 {
831 name: 'Browser',
832 pid: 12345,
833 threads: [
834 {
835 name: 'CrBrowserMain',
836 tid: 1,
837 slices: (() => {
838 const slices = [];
839 for (let i = 0; i < 1000; i += 20) {
840 slices.push({range: [i, i + 10], cpu: 5});
841 }
842 return slices;
843 })(),
844 },
845 {
846 name: 'Chrome_IOThread',
847 tid: 5,
848 slices: (() => {
849 const slices = [];
850 for (let i = 0; i < 1000; i += 100) {
851 slices.push({range: [i, i + 80], cpu: 40});
852 }
853 return slices;
854 })(),
855 }
856 ],
857 },
858 ],
859
860 expectations: [],
861 };
862 }
863
864
865 test('constructMultiDimensionalView_AllThreadsOfSameProcess_' +
866 'singleExpectation', () => {
867 const modelSpec = getAllThreadsOfSameProcessModelSpec_();
868 modelSpec.expectations.push(
869 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
870 range: [0, 90]}
871 );
872
873 const pathForAllThreads = [
874 [CHROME_PROCESS_NAMES.BROWSER], [], ['Animation', 'Video']];
875
876 const pathForThread1 = [
877 [CHROME_PROCESS_NAMES.BROWSER],
878 ['CrBrowserMain'], ['Animation', 'Video']];
879
880 const pathForThread2 = [
881 [CHROME_PROCESS_NAMES.BROWSER],
882 ['Chrome_IOThread'], ['Animation', 'Video']];
883
884 const model = buildModelFromSpec(modelSpec);
885 const root = constructMultiDimensionalView(model, model.bounds);
886 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
887 const valueForThread1 = getNodeValues_(root, pathForThread1);
888 const valueForThread2 = getNodeValues_(root, pathForThread2);
889
890 assert.closeTo(getCpuUsage_(valueForAllThreads),
891 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
892 assert.closeTo(getCpuTotal_(valueForAllThreads),
893 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
894 });
895
896 test('constructMultiDimensionalView_AllThreadsOfSameProcess_' +
897 'disjointExpectationSameInitiator', () => {
898 const modelSpec = getAllThreadsOfSameProcessModelSpec_();
899 modelSpec.expectations.push(
900 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
901 range: [500, 560]},
902 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
903 range: [690, 890]}
904 );
905
906 const pathForAllThreads = [
907 [CHROME_PROCESS_NAMES.BROWSER], [], ['Animation', 'CSS']];
908
909 const pathForThread1 = [
910 [CHROME_PROCESS_NAMES.BROWSER],
911 ['CrBrowserMain'], ['Animation', 'CSS']];
912
913 const pathForThread2 = [
914 [CHROME_PROCESS_NAMES.BROWSER],
915 ['Chrome_IOThread'], ['Animation', 'CSS']];
916
917 const model = buildModelFromSpec(modelSpec);
918 const root = constructMultiDimensionalView(model, model.bounds);
919 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
920 const valueForThread1 = getNodeValues_(root, pathForThread1);
921 const valueForThread2 = getNodeValues_(root, pathForThread2);
922
923 assert.closeTo(getCpuUsage_(valueForAllThreads),
924 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
925 assert.closeTo(getCpuTotal_(valueForAllThreads),
926 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
927 });
928
929 test('constructMultiDimensionalView_AllThreadsOfSameProcess_' +
930 'overlappingExpectationsOfSameInitiator', () => {
931 const modelSpec = getAllThreadsOfSameProcessModelSpec_();
932 // [Scroll R]
933 // [Scroll R]
934 modelSpec.expectations.push(
935 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
936 range: [210, 260]},
937 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
938 range: [250, 300]}
939 );
940
941 const pathForAllThreads = [
942 [CHROME_PROCESS_NAMES.BROWSER], [], ['Response', 'Scroll']];
943
944 const pathForThread1 = [
945 [CHROME_PROCESS_NAMES.BROWSER],
946 ['CrBrowserMain'], ['Response', 'Scroll']];
947
948 const pathForThread2 = [
949 [CHROME_PROCESS_NAMES.BROWSER],
950 ['Chrome_IOThread'], ['Response', 'Scroll']];
951
952 const model = buildModelFromSpec(modelSpec);
953 const root = constructMultiDimensionalView(model, model.bounds);
954 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
955 const valueForThread1 = getNodeValues_(root, pathForThread1);
956 const valueForThread2 = getNodeValues_(root, pathForThread2);
957
958 assert.closeTo(getCpuUsage_(valueForAllThreads),
959 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
960 assert.closeTo(getCpuTotal_(valueForAllThreads),
961 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
962 });
963
964 test('constructMultiDimensionalView_AllThreadsOfSameProcess_' +
965 'disjointExpectationsAllInitiators', () => {
966 const modelSpec = getAllThreadsOfSameProcessModelSpec_();
967 modelSpec.expectations.push(
968 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
969 range: [0, 90]},
970 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
971 range: [500, 560]},
972 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
973 range: [690, 890]}
974 );
975
976 const pathForAllThreads = [
977 [CHROME_PROCESS_NAMES.BROWSER], [], ['Animation', 'all_initiators']];
978
979 const pathForThread1 = [
980 [CHROME_PROCESS_NAMES.BROWSER],
981 ['CrBrowserMain'], ['Animation', 'all_initiators']];
982
983 const pathForThread2 = [
984 [CHROME_PROCESS_NAMES.BROWSER],
985 ['Chrome_IOThread'], ['Animation', 'all_initiators']];
986
987 const model = buildModelFromSpec(modelSpec);
988 const root = constructMultiDimensionalView(model, model.bounds);
989 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
990 const valueForThread1 = getNodeValues_(root, pathForThread1);
991 const valueForThread2 = getNodeValues_(root, pathForThread2);
992
993 assert.closeTo(getCpuUsage_(valueForAllThreads),
994 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
995 assert.closeTo(getCpuTotal_(valueForAllThreads),
996 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
997 });
998
999 test('constructMultiDimensionalView_AllThreadsOfSameProcess_' +
1000 'overlappingExpectationsAllInitiators', () => {
1001 const modelSpec = getAllThreadsOfSameProcessModelSpec_();
1002 // [Click R]
1003 // [Scroll R]
1004 // [Scroll R]
1005 modelSpec.expectations.push(
1006 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
1007 range: [200, 220]},
1008 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1009 range: [210, 260]},
1010 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1011 range: [250, 300]}
1012 );
1013
1014 const pathForAllThreads = [
1015 [CHROME_PROCESS_NAMES.BROWSER], [], ['Response', 'all_initiators']];
1016
1017 const pathForThread1 = [
1018 [CHROME_PROCESS_NAMES.BROWSER],
1019 ['CrBrowserMain'], ['Response', 'all_initiators']];
1020
1021 const pathForThread2 = [
1022 [CHROME_PROCESS_NAMES.BROWSER],
1023 ['Chrome_IOThread'], ['Response', 'all_initiators']];
1024
1025 const model = buildModelFromSpec(modelSpec);
1026 const root = constructMultiDimensionalView(model, model.bounds);
1027 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1028 const valueForThread1 = getNodeValues_(root, pathForThread1);
1029 const valueForThread2 = getNodeValues_(root, pathForThread2);
1030
1031 assert.closeTo(getCpuUsage_(valueForAllThreads),
1032 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1033 assert.closeTo(getCpuTotal_(valueForAllThreads),
1034 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1035 });
1036
1037 test('constructMultiDimensionalView_AllThreadsOfSameProcess_' +
1038 'allStagesAllInitiators', () => {
1039 const modelSpec = getAllThreadsOfSameProcessModelSpec_();
1040 // [Video A] [Click R] [CSS A] [ CSS A ]
1041 // [Scroll R]
1042 // [Scroll R]
1043 modelSpec.expectations.push(
1044 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
1045 range: [0, 90]},
1046 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
1047 range: [200, 220]},
1048 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1049 range: [210, 260]},
1050 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1051 range: [250, 300]},
1052 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1053 range: [500, 560]},
1054 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1055 range: [690, 890]}
1056 );
1057
1058 const pathForAllThreads = [
1059 [CHROME_PROCESS_NAMES.BROWSER], [], ['all_stages', 'all_initiators']];
1060
1061 const pathForThread1 = [
1062 [CHROME_PROCESS_NAMES.BROWSER],
1063 ['CrBrowserMain'], ['all_stages', 'all_initiators']];
1064
1065 const pathForThread2 = [
1066 [CHROME_PROCESS_NAMES.BROWSER],
1067 ['Chrome_IOThread'], ['all_stages', 'all_initiators']];
1068
1069 const model = buildModelFromSpec(modelSpec);
1070 const root = constructMultiDimensionalView(model, model.bounds);
1071 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1072 const valueForThread1 = getNodeValues_(root, pathForThread1);
1073 const valueForThread2 = getNodeValues_(root, pathForThread2);
1074
1075 assert.closeTo(getCpuUsage_(valueForAllThreads),
1076 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1077 assert.closeTo(getCpuTotal_(valueForAllThreads),
1078 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1079 });
1080
1081 /**
1082 * Returns a model spec where a renderer process and a GPU process both have a
1083 * Chrome_ChildIOThread.
1084 *
1085 * This is a function instead of just a variable because the test functions
1086 * are meant to modify this modelSpec and insert suitable expectations.
1087 *
1088 * The modelSpec includes a basic browser process because it not a valid
1089 * chrome model otherwise.
1090 */
1091 function getAllProcessesOfSameThreadModelSpec_() {
1092 return {
1093 processes: [
1094 {
1095 name: 'Browser',
1096 pid: 12345,
1097 threads: [
1098 {
1099 name: 'CrBrowserMain',
1100 tid: 1,
1101 slices: [],
1102 },
1103 ],
1104 },
1105 {
1106 name: 'Renderer',
1107 pid: 20001,
1108 threads: [
1109 {
1110 name: 'Chrome_ChildIOThread',
1111 tid: 42,
1112 slices: (() => {
1113 const slices = [];
1114 for (let i = 0; i < 1000; i += 20) {
1115 slices.push({range: [i, i + 10], cpu: 5});
1116 }
1117 return slices;
1118 })(),
1119 },
1120 ],
1121 },
1122 {
1123 name: 'GPU Process',
1124 pid: 30001,
1125 threads: [
1126 {
1127 name: 'Chrome_ChildIOThread',
1128 tid: 52,
1129 slices: (() => {
1130 const slices = [];
1131 for (let i = 0; i < 1000; i += 100) {
1132 slices.push({range: [i, i + 80], cpu: 40});
1133 }
1134 return slices;
1135 })(),
1136 },
1137 ]
1138 },
1139 ],
1140 expectations: [],
1141 };
1142 }
1143
1144 test('constructMultiDimensionalView_AllProcessesOfSameThread_' +
1145 'singleExpectation', () => {
1146 const modelSpec = getAllProcessesOfSameThreadModelSpec_();
1147 modelSpec.expectations.push(
1148 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
1149 range: [0, 90]}
1150 );
1151
1152 const pathForAllThreads = [
1153 [], ['Chrome_ChildIOThread'], ['Animation', 'Video']];
1154
1155 const pathForThread1 = [
1156 [CHROME_PROCESS_NAMES.RENDERER],
1157 ['Chrome_ChildIOThread'], ['Animation', 'Video']];
1158
1159 const pathForThread2 = [
1160 [CHROME_PROCESS_NAMES.GPU],
1161 ['Chrome_ChildIOThread'], ['Animation', 'Video']];
1162
1163 const model = buildModelFromSpec(modelSpec);
1164 const root = constructMultiDimensionalView(model, model.bounds);
1165 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1166 const valueForThread1 = getNodeValues_(root, pathForThread1);
1167 const valueForThread2 = getNodeValues_(root, pathForThread2);
1168
1169 assert.closeTo(getCpuUsage_(valueForAllThreads),
1170 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1171 assert.closeTo(getCpuTotal_(valueForAllThreads),
1172 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1173 });
1174
1175 test('constructMultiDimensionalView_AllProcessesOfSameThread_' +
1176 'disjointExpectationSameInitiator', () => {
1177 const modelSpec = getAllProcessesOfSameThreadModelSpec_();
1178 modelSpec.expectations.push(
1179 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1180 range: [500, 560]},
1181 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1182 range: [690, 890]}
1183 );
1184
1185 const pathForAllThreads = [
1186 [], ['Chrome_ChildIOThread'], ['Animation', 'CSS']];
1187
1188 const pathForThread1 = [
1189 [CHROME_PROCESS_NAMES.RENDERER],
1190 ['Chrome_ChildIOThread'], ['Animation', 'CSS']];
1191
1192 const pathForThread2 = [
1193 [CHROME_PROCESS_NAMES.GPU],
1194 ['Chrome_ChildIOThread'], ['Animation', 'CSS']];
1195
1196 const model = buildModelFromSpec(modelSpec);
1197 const root = constructMultiDimensionalView(model, model.bounds);
1198 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1199 const valueForThread1 = getNodeValues_(root, pathForThread1);
1200 const valueForThread2 = getNodeValues_(root, pathForThread2);
1201
1202 assert.closeTo(getCpuUsage_(valueForAllThreads),
1203 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1204 assert.closeTo(getCpuTotal_(valueForAllThreads),
1205 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1206 });
1207
1208 test('constructMultiDimensionalView_AllProcessesOfSameThread_' +
1209 'overlappingExpectationsOfSameInitiator', () => {
1210 const modelSpec = getAllProcessesOfSameThreadModelSpec_();
1211 // [Scroll R]
1212 // [Scroll R]
1213 modelSpec.expectations.push(
1214 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1215 range: [210, 260]},
1216 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1217 range: [250, 300]}
1218 );
1219
1220 const pathForAllThreads = [
1221 [], ['Chrome_ChildIOThread'], ['Response', 'Scroll']];
1222
1223 const pathForThread1 = [
1224 [CHROME_PROCESS_NAMES.RENDERER],
1225 ['Chrome_ChildIOThread'], ['Response', 'Scroll']];
1226
1227 const pathForThread2 = [
1228 [CHROME_PROCESS_NAMES.GPU],
1229 ['Chrome_ChildIOThread'], ['Response', 'Scroll']];
1230
1231 const model = buildModelFromSpec(modelSpec);
1232 const root = constructMultiDimensionalView(model, model.bounds);
1233 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1234
1235 const valueForThread1 = getNodeValues_(root, pathForThread1);
1236 const valueForThread2 = getNodeValues_(root, pathForThread2);
1237
1238 assert.closeTo(getCpuUsage_(valueForAllThreads),
1239 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1240 assert.closeTo(getCpuTotal_(valueForAllThreads),
1241 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1242 });
1243
1244 test('constructMultiDimensionalView_AllProcessesOfSameThread_' +
1245 'disjointExpectationsAllInitiators', () => {
1246 const modelSpec = getAllProcessesOfSameThreadModelSpec_();
1247 modelSpec.expectations.push(
1248 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
1249 range: [0, 90]},
1250 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1251 range: [500, 560]},
1252 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1253 range: [690, 890]}
1254 );
1255
1256 const pathForAllThreads = [
1257 [], ['Chrome_ChildIOThread'], ['Animation', 'all_initiators']];
1258
1259 const pathForThread1 = [
1260 [CHROME_PROCESS_NAMES.RENDERER],
1261 ['Chrome_ChildIOThread'], ['Animation', 'all_initiators']];
1262
1263 const pathForThread2 = [
1264 [CHROME_PROCESS_NAMES.GPU],
1265 ['Chrome_ChildIOThread'], ['Animation', 'all_initiators']];
1266
1267 const model = buildModelFromSpec(modelSpec);
1268 const root = constructMultiDimensionalView(model, model.bounds);
1269 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1270 const valueForThread1 = getNodeValues_(root, pathForThread1);
1271 const valueForThread2 = getNodeValues_(root, pathForThread2);
1272
1273 assert.closeTo(getCpuUsage_(valueForAllThreads),
1274 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1275 assert.closeTo(getCpuTotal_(valueForAllThreads),
1276 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1277 });
1278
1279 test('constructMultiDimensionalView_AllProcessesOfSameThread_' +
1280 'overlappingExpectationsAllInitiators', () => {
1281 const modelSpec = getAllProcessesOfSameThreadModelSpec_();
1282 // [Click R]
1283 // [Scroll R]
1284 // [Scroll R]
1285 modelSpec.expectations.push(
1286 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
1287 range: [200, 220]},
1288 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1289 range: [210, 260]},
1290 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1291 range: [250, 300]}
1292 );
1293
1294 const pathForAllThreads = [
1295 [], ['Chrome_ChildIOThread'], ['Response', 'all_initiators']];
1296
1297 const pathForThread1 = [
1298 [CHROME_PROCESS_NAMES.RENDERER],
1299 ['Chrome_ChildIOThread'], ['Response', 'all_initiators']];
1300
1301 const pathForThread2 = [
1302 [CHROME_PROCESS_NAMES.GPU],
1303 ['Chrome_ChildIOThread'], ['Response', 'all_initiators']];
1304
1305 const model = buildModelFromSpec(modelSpec);
1306 const root = constructMultiDimensionalView(model, model.bounds);
1307 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1308 const valueForThread1 = getNodeValues_(root, pathForThread1);
1309 const valueForThread2 = getNodeValues_(root, pathForThread2);
1310
1311 assert.closeTo(getCpuUsage_(valueForAllThreads),
1312 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1313 assert.closeTo(getCpuTotal_(valueForAllThreads),
1314 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1315 });
1316
1317 test('constructMultiDimensionalView_AllProcessesOfSameThread_' +
1318 'allStagesAllInitiators', () => {
1319 const modelSpec = getAllProcessesOfSameThreadModelSpec_();
1320 // [Video A] [Click R] [CSS A] [ CSS A ]
1321 // [Scroll R]
1322 // [Scroll R]
1323 modelSpec.expectations.push(
1324 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
1325 range: [0, 90]},
1326 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
1327 range: [200, 220]},
1328 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1329 range: [210, 260]},
1330 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1331 range: [250, 300]},
1332 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1333 range: [500, 560]},
1334 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1335 range: [690, 890]}
1336 );
1337
1338 const pathForAllThreads = [
1339 [], ['Chrome_ChildIOThread'], ['all_stages', 'all_initiators']];
1340
1341 const pathForThread1 = [
1342 [CHROME_PROCESS_NAMES.RENDERER],
1343 ['Chrome_ChildIOThread'], ['all_stages', 'all_initiators']];
1344
1345 const pathForThread2 = [
1346 [CHROME_PROCESS_NAMES.GPU],
1347 ['Chrome_ChildIOThread'], ['all_stages', 'all_initiators']];
1348
1349 const model = buildModelFromSpec(modelSpec);
1350 const root = constructMultiDimensionalView(model, model.bounds);
1351 const valueForAllThreads = getNodeValues_(root, pathForAllThreads);
1352 const valueForThread1 = getNodeValues_(root, pathForThread1);
1353 const valueForThread2 = getNodeValues_(root, pathForThread2);
1354
1355 assert.closeTo(getCpuUsage_(valueForAllThreads),
1356 getCpuUsage_(valueForThread1) + getCpuUsage_(valueForThread2), 1e-7);
1357 assert.closeTo(getCpuTotal_(valueForAllThreads),
1358 getCpuTotal_(valueForThread1) + getCpuTotal_(valueForThread2), 1e-7);
1359 });
1360
1361 test('constructMultiDimensionalView_completeAggregation', () => {
1362 const modelSpec = {
1363 processes: [
1364 {
1365 name: 'Browser',
1366 pid: 12345,
1367 threads: [
1368 {
1369 name: 'CrBrowserMain',
1370 tid: 1,
1371 slices: (() => {
1372 const slices = [];
1373 for (let i = 0; i < 1000; i += 50) {
1374 slices.push({range: [i, i + 50], cpu: 30});
1375 }
1376 return slices;
1377 })(),
1378 },
1379 ],
1380 },
1381 {
1382 name: 'Renderer',
1383 pid: 20001,
1384 threads: [
1385 {
1386 name: 'Chrome_ChildIOThread',
1387 tid: 42,
1388 slices: (() => {
1389 const slices = [];
1390 for (let i = 0; i < 1000; i += 20) {
1391 slices.push({range: [i, i + 10], cpu: 5});
1392 }
1393 return slices;
1394 })(),
1395 },
1396 ],
1397 },
1398 {
1399 name: 'GPU Process',
1400 pid: 30001,
1401 threads: [
1402 {
1403 name: 'Chrome_ChildIOThread',
1404 tid: 52,
1405 slices: (() => {
1406 const slices = [];
1407 for (let i = 0; i < 1000; i += 100) {
1408 slices.push({range: [i, i + 80], cpu: 40});
1409 }
1410 return slices;
1411 })(),
1412 },
1413 ]
1414 },
1415 ],
1416
1417 // [Video A] [Click R] [CSS A] [ CSS A ]
1418 // [Scroll R]
1419 // [Scroll R]
1420 expectations: [
1421 {stage: 'Animation', initiatorType: INITIATOR_TYPE.VIDEO,
1422 range: [0, 90]},
1423 {stage: 'Response', initiatorType: INITIATOR_TYPE.CLICK,
1424 range: [200, 220]},
1425 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1426 range: [210, 260]},
1427 {stage: 'Response', initiatorType: INITIATOR_TYPE.SCROLL,
1428 range: [250, 300]},
1429 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1430 range: [500, 560]},
1431 {stage: 'Animation', initiatorType: INITIATOR_TYPE.CSS,
1432 range: [690, 890]}
1433 ],
1434 };
1435
1436 const model = buildModelFromSpec(modelSpec);
1437 const path = [[], [], ['all_stages'], ['all_initiators']];
1438 const root = constructMultiDimensionalView(model, model.bounds);
1439 const values = getNodeValues_(root, path);
1440
1441 assert.closeTo(getCpuUsage_(values),
1442 (30 * 20 + 5 * 50 + 40 * 10) / 1000, 1e-7);
1443 assert.closeTo(getCpuTotal_(values),
1444 (30 * 20 + 5 * 50 + 40 * 10), 1e-7);
1445 });
163 }); 1446 });
1447
164 </script> 1448 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698