Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 <!DOCTYPE html> | |
| 2 <!-- | |
| 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 | |
| 5 found in the LICENSE file. | |
| 6 --> | |
| 7 | |
| 8 | |
| 9 <script> | |
| 10 'use strict'; | |
| 11 | |
| 12 tr.exportTo('tr.e.chrome.cpuTimeTestUtils', function() { | |
| 13 /** | |
| 14 * Takes a model spec, and returns a fully constructed model. | |
| 15 * | |
| 16 * A model spec is a minimal representation of a model containing only the | |
| 17 * information needed to set up scenarios for testing cpu time metrics - it | |
| 18 * specifies | |
| 19 * - All the processes with name, pid, and threads | |
| 20 * - All the threads with name, tid, and top level slices | |
| 21 * - All the top level slices with range and cpu duration | |
| 22 * - All the User Expectations (except Idle Expectations) with range, stage, | |
| 23 * and initiator. | |
| 24 * | |
| 25 * Example model spec: | |
| 26 * { | |
| 27 * processes: [ | |
| 28 * { | |
| 29 * name: 'Browser', | |
| 30 * pid: 12345, | |
| 31 * threads: [ | |
| 32 * { | |
| 33 * name: 'CrBrowserMain', | |
| 34 * tid: 1, | |
| 35 * slices: [ | |
| 36 * {range: [150, 200], cpu: 30}, | |
| 37 * {range: [205, 255], cpu: 20} | |
| 38 * ] | |
| 39 * }, | |
| 40 * ], | |
| 41 * }, | |
| 42 * ], | |
| 43 * expectations: [ | |
| 44 * {stage: 'Animation', initiatorType: 'Video', range: [0, 90]}, | |
| 45 * {stage: 'Response', initiatorType: 'Click', range: [200, 220]}, | |
| 46 * ] | |
| 47 * } | |
| 48 */ | |
| 49 function buildModelFromSpec(modelSpec) { | |
| 50 return tr.c.TestUtils.newModel(model => { | |
| 51 // Create processes, threads, and slices | |
| 52 for (const processSpec of modelSpec.processes) { | |
| 53 const process = model.getOrCreateProcess(processSpec.pid); | |
| 54 process.name = processSpec.name; | |
| 55 | |
| 56 for (const threadSpec of processSpec.threads) { | |
| 57 const thread = process.getOrCreateThread(threadSpec.tid); | |
| 58 thread.name = threadSpec.name; | |
| 59 | |
| 60 for (const sliceSpec of threadSpec.slices) { | |
| 61 // Sanity checks on sliceSpec | |
| 62 const sliceStart = sliceSpec.range[0]; | |
| 63 const sliceEnd = sliceSpec.range[1]; | |
| 64 const duration = sliceEnd - sliceStart; | |
| 65 const cpuDuration = sliceSpec.cpu; | |
| 66 assert(sliceEnd >= sliceStart, | |
| 67 'Slice end time is earlier than slice start time: ' + | |
| 68 `sliceStart: ${sliceStart}, sliceEnd: ${sliceEnd}`); | |
| 69 assert(duration >= cpuDuration, | |
| 70 `Cpu duration (${cpuDuration}) is larger than ` + | |
| 71 `slice duration (${duration})`); | |
| 72 | |
| 73 thread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({ | |
| 74 type: tr.model.ThreadSlice, | |
| 75 isTopLevel: true, | |
| 76 start: sliceSpec.range[0], | |
| 77 duration: sliceSpec.range[1] - sliceSpec.range[0], | |
| 78 // We currently do not have all the data about exactly when a | |
| 79 // thread was scheduled or descheduled - for example, if a slice | |
| 80 // got descheduled twice over its duration, the trace will not | |
| 81 // contain information to indicate that. Without loss of | |
| 82 // generality, we therefore make the assumption that the cpuStart | |
| 83 // is at the beginning of the slice, and total cpu time of a slice | |
| 84 // is uniformly spread over its duration. | |
| 85 cpuStart: sliceSpec.range[0], | |
| 86 cpuDuration: sliceSpec.cpu | |
| 87 })); | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 const expectations = model.userModel.expectations; | |
| 93 for (const expSpec of modelSpec.expectations) { | |
| 94 // This switch statement is not exhaustive. You may have to add more | |
| 95 // cases here when you add new scenarios. | |
| 96 switch (expSpec.stage) { | |
| 97 case 'Animation': | |
| 98 expectations.push(new tr.model.um.AnimationExpectation( | |
| 99 model, expSpec.initiatorType, | |
| 100 expSpec.range[0], expSpec.range[1] - expSpec.range[0] | |
| 101 )); | |
| 102 break; | |
| 103 case 'Idle': | |
| 104 expectations.push(new tr.model.um.IdleExpectation( | |
| 105 model, expSpec.range[0], expSpec.range[1] - expSpec.range[0] | |
| 106 )); | |
| 107 break; | |
| 108 case 'Response': | |
| 109 expectations.push(new tr.model.um.ResponseExpectation( | |
| 110 model, expSpec.initiatorType, | |
| 111 expSpec.range[0], expSpec.range[1] - expSpec.range[0] | |
| 112 )); | |
| 113 break; | |
| 114 default: | |
| 115 throw new Error('Internal Error: Stage ' + expSpec.stage | |
| 116 + 'not handled yet. You should add another case here.'); | |
| 117 } | |
| 118 } | |
| 119 }); | |
| 120 } | |
| 121 | |
| 122 /** | |
| 123 * Returns a simple model spec with one process (browser process) and one | |
| 124 * thread (CrBrowserMain). | |
| 125 * | |
| 126 * It does not contain any slices or expectations - those should be added | |
| 127 * manually. | |
| 128 */ | |
| 129 function getSimpleModelSpec() { | |
| 130 return { | |
| 131 processes: [ | |
| 132 { | |
| 133 name: 'Browser', | |
| 134 pid: 12345, | |
| 135 threads: [ | |
| 136 { | |
| 137 name: 'CrBrowserMain', | |
| 138 tid: 1, | |
| 139 slices: [] | |
| 140 }, | |
| 141 ], | |
| 142 }, | |
| 143 ], | |
| 144 expectations: [], | |
| 145 }; | |
| 146 } | |
| 147 | |
| 148 return { | |
| 149 buildModelFromSpec, | |
| 150 getSimpleModelSpec, | |
| 151 }; | |
| 152 | |
|
benjhayden
2017/04/07 18:05:17
no blank lines at starts or ends of blocks
| |
| 153 }); | |
| 154 </script> | |
| OLD | NEW |