Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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> |
| OLD | NEW |