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

Unified Diff: tracing/tracing/metrics/system_health/cpu_time_metric_test.html

Issue 2804043003: [WIP] [DEFINITELY NOT READY TO LAND] Cpu time metric implementation (Closed)
Patch Set: pick up changes from children Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tracing/tracing/metrics/system_health/cpu_time_metric.html ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tracing/tracing/metrics/system_health/cpu_time_metric_test.html
diff --git a/tracing/tracing/metrics/system_health/cpu_time_metric_test.html b/tracing/tracing/metrics/system_health/cpu_time_metric_test.html
index 3405d82e1f9e13c742e1bd324bcfcf11bfd498be..f13644c63458b135b5c0b17515945ef71b5c6907 100644
--- a/tracing/tracing/metrics/system_health/cpu_time_metric_test.html
+++ b/tracing/tracing/metrics/system_health/cpu_time_metric_test.html
@@ -7,6 +7,7 @@ found in the LICENSE file.
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/extras/chrome/chrome_test_utils.html">
+<link rel="import" href="/tracing/extras/chrome/cpu_time_test_utils.html">
<link rel="import" href="/tracing/metrics/system_health/cpu_time_metric.html">
<link rel="import" href="/tracing/value/histogram_set.html">
@@ -14,146 +15,643 @@ found in the LICENSE file.
'use strict';
tr.b.unittest.testSuite(function() {
- function computeCpuTime(customizeModelCallback, opt_options) {
- const model = tr.c.TestUtils.newModel(function(model) {
- customizeModelCallback(model);
- });
+ const getThreadType = tr.metrics.sh.getThreadType;
+ const calculateCpuTimeFragment = tr.metrics.sh.calculateCpuTimeFragment;
+
+ const CHROME_PROCESS_NAMES =
+ tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES;
+
+ const buildModelFromSpec = tr.e.chrome.cpuTimeTestUtils.buildModelFromSpec;
+ const getSimpleModelSpec = tr.e.chrome.cpuTimeTestUtils.getSimpleModelSpec;
+
+ // A very small epsilon to assert with acceptable precision the correctness of
+ // small floating point values produced by cpu time metric.
+ const EPSILON7 = 1e-7;
+
+ // Shorthand for initiator types
+ const IT = tr.model.um.INITIATOR_TYPE;
+
+ function computeMetricValue(modelSpec, metricName, opt_rangeOfInterest) {
+ const model = buildModelFromSpec(modelSpec);
const histograms = new tr.v.HistogramSet();
- tr.metrics.sh.cpuTimeMetric(histograms, model, opt_options);
- return tr.b.getOnlyElement(histograms).average;
+ const options = opt_rangeOfInterest ?
+ {rangeOfInterest: opt_rangeOfInterest} : undefined;
+ tr.metrics.sh.cpuTimeMetric(histograms, model, options);
+ return histograms.getHistogramNamed(metricName).sum;
}
- // There are two slices, each of length 50. The total bounds is 3000.
- // This yields total CPU time of 100ms, averaged over 3 seconds is 33ms.
- test('cpuTimeMetric_oneProcess', function() {
- const sliceDuration = 50;
- const totalDuration = 3000;
- const value = computeCpuTime(function(model) {
- model.rendererProcess = model.getOrCreateProcess(2);
- model.rendererMain = model.rendererProcess.getOrCreateThread(3);
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: 0,
- duration: sliceDuration,
- cpuStart: 0,
- cpuDuration: sliceDuration,
- }));
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: totalDuration - sliceDuration,
- duration: sliceDuration,
- cpuStart: totalDuration - sliceDuration,
- cpuDuration: sliceDuration,
- }));
- });
- assert.closeTo(value, 0.033, 0.001);
+ function assertMetricValueInHistogram(histograms, metricName, expectedValue) {
+ const value = histograms.getHistogramNamed(metricName).sum;
+ assert.closeTo(value, expectedValue, EPSILON7);
+ }
+
+ // TODO: DO NOT COMMIT THIS. Fix all instances. This is a temporary
+ // workaround while I get the higher level structure of the code sorted out.
+ function fixMetricName(name) {
+ const parts = name.split(':');
+ if (parts[1] === 'GPU') parts[1] = 'gpu_process';
+ parts[1] = tr.e.chrome.chrome_processes.canonicalizeProcessName(parts[1]);
+ parts[0] = "cpuUsage";
+ return parts.join(":");
+ }
+
+ test('slicesDoNotStraddleExpecationBoundaries', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Animation', initiatorType: IT.CSS, range: [100, 300]}
+ )
+ const metricName = `cpuUsage:${CHROME_PROCESS_NAMES.BROWSER}:` +
+ `CrBrowserMain:Animation:CSS`;
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, (30 + 20) / 200, EPSILON7);
+ });
+
+ test('slicesStraddleExpectationBoundaries', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [75, 175]}
+ )
+ const metricName = `cpuUsage:${CHROME_PROCESS_NAMES.BROWSER}:` +
+ `CrBrowserMain:Animation:Video`;
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, 15 / 100, EPSILON7);
+ });
+
+ test('singleThread-disjointExpectationsOfSameInitiator', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [100, 160]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [205, 225]}
+ )
+ const metricName = `cpuUsage:${CHROME_PROCESS_NAMES.BROWSER}` +
+ `:CrBrowserMain:Response:Scroll`;
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, (0.2 * 30 + 0.4 * 20) / (60 + 20), EPSILON7);
+ });
+
+ test('singleThread-overlappingExpectationsOfSameInitiator', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [100, 190]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [170, 230]}
+ )
+ const metricName = fixMetricName('cpuTime:Browser:CrBrowserMain:Response:Scroll');
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, (30 + .5 * 20) / 130, EPSILON7);
+ });
+
+ test('singleThread-disjointExpectationsOfDifferentInitiators', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Animation', initiatorType: IT.CSS, range: [100, 160]},
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [205, 230]}
+ );
+ const metricName = fixMetricName('cpuTime:Browser:CrBrowserMain:Animation:all_initiators');
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, (0.2 * 30 + 0.5 * 20) / 85, EPSILON7);
+ });
+
+ test('singleThread-overlappingExpectationsOfDifferentInitiators', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Animation', initiatorType: IT.CSS, range: [100, 190]},
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [160, 230]}
+ );
+ const metricName = fixMetricName('cpuTime:Browser:CrBrowserMain:Animation:all_initiators');
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, (30 + 0.5 * 20) / 130, EPSILON7);
});
- // Normalize against the browser process, whose non-CPU slice goes from 2900
- // to 3000.
- test('cpuTimeMetric_browserProcess', function() {
- const sliceDuration = 50;
- const totalDuration = 3000;
- const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
- model.browserMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: totalDuration - 2 * sliceDuration,
- duration: 2 * sliceDuration,
- }));
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: 0,
- duration: sliceDuration,
- cpuStart: 0,
- cpuDuration: sliceDuration,
- }));
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: totalDuration - sliceDuration,
- duration: sliceDuration,
- cpuStart: totalDuration - sliceDuration,
- cpuDuration: sliceDuration,
- }));
- });
+ test('singleThread-allStages-customRangeOfInterest', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Animation', initiatorType: IT.CSS, range: [100, 190]},
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [160, 230]}
+ );
+ const metricName = fixMetricName('cpuTime:Browser:CrBrowserMain:all_stages:all_initiators');
+ const rangeOfInterest = new tr.b.math.Range.fromExplicitRange(100, 210);
+ const value = computeMetricValue(
+ simpleModelSpec, metricName, rangeOfInterest);
+ assert.closeTo(value, (30 + 0.1 * 20)/ 110, EPSILON7);
+ });
+
+ test('singleThread-allStages-defaultRangeOfInterest', () => {
+ const simpleModelSpec = getSimpleModelSpec();
+ simpleModelSpec.processes[0].threads[0].slices.push(
+ {range: [150, 200], cpu: 30},
+ {range: [205, 255], cpu: 20}
+ )
+ simpleModelSpec.expectations.push(
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [160, 230]}
+ );
+ const metricName = fixMetricName('cpuTime:Browser:CrBrowserMain:all_stages:all_initiators');
+ const value = computeMetricValue(simpleModelSpec, metricName);
+ assert.closeTo(value, 50 / 105, EPSILON7);
+ });
+
+ test('multipleThreadsOfSameTypeAggregate', () => {
+ const modelSpec = {
+ processes: [
+ {
+ name: 'Browser',
+ pid: 12345,
+ threads: [
+ {
+ name: 'CrBrowserMain',
+ tid: 1,
+ slices: [],
+ },
+ {
+ name: 'Worker/1',
+ tid: 42,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 20) {
+ slices.push({range:[i, i + 10], cpu: 5});
+ }
+ return slices;
+ })(),
+ },
+ {
+ name: 'Worker/2',
+ tid: 52,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 100) {
+ slices.push({range:[i, i + 80], cpu: 40});
+ }
+ return slices;
+ })(),
+ },
+ ],
+ },
+ ],
+
+ // [Video A] [Click R] [CSS A] [ CSS A ]
+ // [Scroll R]
+ // [Scroll R]
+ expectations: [
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [0, 90]},
+
+ {stage: 'Response', initiatorType: IT.CLICK, range: [200, 220]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [210, 260]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [250, 300]},
+
+
+ {stage: 'Animation', initiatorType: IT.CSS, range: [500, 560]},
+ {stage: 'Animation', initiatorType: IT.CSS, range: [690, 890]},
+ ],
+ };
+
+ const model = buildModelFromSpec(modelSpec);
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.cpuTimeMetric(histograms, model);
- const value = tr.b.getOnlyElement(histograms).average;
- assert.closeTo(value, 0.5, 0.001);
+
+ // Single expectation range of same initiator type.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Browser:Worker:Animation:Video'),
+ (5 * 5 + 40) / 90);
+
+ // Disjoint expectation ranges of same initiator type.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Browser:Worker:Animation:CSS'),
+ ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)) / (60 + 200));
+
+ // Overlapping expectation ranges of same initiator type.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Browser:Worker:Response:Scroll'),
+ (5 * 4 + 40 * (70 / 80))/ 90);
+
+ // Disjoint expectation ranges with all_initiators.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Browser:Worker:Animation:all_initiators'),
+ ((5 * 5 + 40)
+ + ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)))
+ / (90 + 60 + 200));
+
+ // Overlapping expectation ranges with all_initiators.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Browser:Worker:Response:all_initiators'),
+ (5 * 5 + 40) / 100);
+
+ // all_stages and all_initiators.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Browser:Worker:all_stages:all_initiators'),
+ (250 + 400) / 990);
});
- // Makes sure that rangeOfInterest works correctly.
- test('cpuTimeMetric_oneProcess_rangeOfInterest', function() {
- const sliceDuration = 50;
- const totalDuration = 3000;
- const rangeOfInterest = new tr.b.math.Range.fromExplicitRange(-10, 30);
- const options = {};
- options.rangeOfInterest = rangeOfInterest;
- const value = computeCpuTime(function(model) {
- model.rendererProcess = model.getOrCreateProcess(2);
- model.rendererMain = model.rendererProcess.getOrCreateThread(3);
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: 0,
- duration: sliceDuration,
- cpuStart: 0,
- cpuDuration: sliceDuration,
- }));
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: totalDuration - sliceDuration,
- duration: sliceDuration,
- cpuStart: totalDuration - sliceDuration,
- cpuDuration: sliceDuration,
- }));
- }, options);
- assert.closeTo(value, 0.75, 0.001);
+ test('multipleProcessesOfSameTypeAggregate', () => {
+ const modelSpec = {
+ processes: [
+ {
+ name: 'Browser',
+ pid: 12345,
+ threads: [
+ {
+ name: 'CrBrowserMain',
+ tid: 1,
+ slices: [],
+ },
+ ],
+ },
+ {
+ name: 'Renderer',
+ pid: 20001,
+ threads: [
+ {
+ name: 'CrRendererMain',
+ tid: 42,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 20) {
+ slices.push({range:[i, i + 10], cpu: 5});
+ }
+ return slices;
+ })(),
+ },
+ ],
+ },
+ {
+ name: 'Renderer',
+ pid: 30001,
+ threads: [
+ {
+ name: 'CrRendererMain',
+ tid: 52,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 100) {
+ slices.push({range:[i, i + 80], cpu: 40});
+ }
+ return slices;
+ })(),
+ },
+ ]
+ },
+ ],
+
+ // [Video A] [Click R] [CSS A] [ CSS A ]
+ // [Scroll R]
+ // [Scroll R]
+ expectations: [
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [0, 90]},
+
+ {stage: 'Response', initiatorType: IT.CLICK, range: [200, 220]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [210, 260]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [250, 300]},
+
+
+ {stage: 'Animation', initiatorType: IT.CSS, range: [500, 560]},
+ {stage: 'Animation', initiatorType: IT.CSS, range: [690, 890]},
+ ],
+ };
+
+ const model = buildModelFromSpec(modelSpec);
+ const histograms = new tr.v.HistogramSet();
+ tr.metrics.sh.cpuTimeMetric(histograms, model);
+
+ // Single expectation range of same initiator type.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Renderer:CrRendererMain:Animation:Video'),
+ (5 * 5 + 40) / 90);
+
+ // Disjoint expectation ranges of same initiator type.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Renderer:CrRendererMain:Animation:CSS'),
+ ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)) / (60 + 200));
+
+ // Overlapping expectation ranges of same initiator type.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Renderer:CrRendererMain:Response:Scroll'),
+ (5 * 4 + 40 * (70 / 80))/ 90);
+
+ // Disjoint expectation ranges with all_initiators.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Renderer:CrRendererMain:Animation:all_initiators'),
+ ((5 * 5 + 40)
+ + ((5 * 3 + 40 * (60 / 80)) + (5 * 10 + 40 * 2)))
+ / (90 + 60 + 200));
+
+ // Overlapping expectation ranges with all_initiators.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Renderer:CrRendererMain:Response:all_initiators'),
+ (5 * 5 + 40) / 100);
+
+ // all_stages and all_initiators.
+ assertMetricValueInHistogram(histograms,
+ fixMetricName('cpuTime:Renderer:CrRendererMain:all_stages:all_initiators'),
+ (250 + 400) / 990);
+ });
+
+ test('allThreadsOfSameProcessAggregate', () => {
+ const modelSpec = {
+ processes: [
+ {
+ name: 'Browser',
+ pid: 12345,
+ threads: [
+ {
+ name: 'CrBrowserMain',
+ tid: 1,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 20) {
+ slices.push({range:[i, i + 10], cpu: 5});
+ }
+ return slices;
+ })(),
+ },
+ {
+ name: 'Chrome_IOThread',
+ tid: 5,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 100) {
+ slices.push({range:[i, i + 80], cpu: 40});
+ }
+ return slices;
+ })(),
+ }
+ ],
+ },
+ ],
+
+ // [Video A] [Click R] [CSS A] [ CSS A ]
+ // [Scroll R]
+ // [Scroll R]
+ expectations: [
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [0, 90]},
+
+ {stage: 'Response', initiatorType: IT.CLICK, range: [200, 220]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [210, 260]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [250, 300]},
+
+
+ {stage: 'Animation', initiatorType: IT.CSS, range: [500, 560]},
+ {stage: 'Animation', initiatorType: IT.CSS, range: [690, 890]},
+ ],
+ };
+
+ const model = buildModelFromSpec(modelSpec);
+ const histograms = new tr.v.HistogramSet();
+ tr.metrics.sh.cpuTimeMetric(histograms, model);
+
+ const subMetricPrefix1 =
+ 'cpuTime:Browser:CrBrowserMain';
+ const subMetricPrefix2 =
+ 'cpuTime:Browser:Chrome_IOThread';
+ const aggregateMetricPrefix =
+ 'cpuTime:Browser:all_threads';
+
+ function getMetricValueFromHistogram(histograms, metricName) {
+ return histograms.getHistogramNamed(fixMetricName(metricName)).sum;
+ }
+
+ const metricSuffixes = [
+ // Single expectation range of same initiator type.
+ 'Animation:Video',
+ // Disjoint expectation ranges of same initiator type.
+ 'Animation:CSS',
+ // Overlapping expectation ranges of same initiator type.
+ 'Response:Scroll',
+ // Disjoint expectation ranges with all_initiators.
+ 'Animation:all_initiators',
+ // Overlapping expectation ranges with all_initiators.
+ 'Response:all_initiators',
+ // all_stages and all_initiators.
+ 'all_stages:all_initiators',
+ ]
+
+ for (const suffix of metricSuffixes) {
+ const subMetric1 = getMetricValueFromHistogram(histograms,
+ `${subMetricPrefix1}:${suffix}`);
+ const subMetric2 = getMetricValueFromHistogram(histograms,
+ `${subMetricPrefix2}:${suffix}`);
+ const aggregateMetric = getMetricValueFromHistogram(histograms,
+ `${aggregateMetricPrefix}:${suffix}`);
+ assert.closeTo(aggregateMetric, subMetric1 + subMetric2, EPSILON7);
+ }
});
- // Process 1: There are two slices, each of length 50. The total bounds is
- // 3000. Process 2: There is one slice of length 50.
- // This yields total CPU time of 150ms, averaged over 3 seconds is 50ms.
- test('cpuTimeMetric_twoProcesses', function() {
- const sliceDuration = 50;
- const totalDuration = 3000;
- const value = computeCpuTime(function(model) {
- model.rendererProcess = model.getOrCreateProcess(2);
- model.rendererMain = model.rendererProcess.getOrCreateThread(3);
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: 0,
- duration: sliceDuration,
- cpuStart: 0,
- cpuDuration: sliceDuration,
- }));
- model.rendererMain.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: totalDuration - sliceDuration,
- duration: sliceDuration,
- cpuStart: totalDuration - sliceDuration,
- cpuDuration: sliceDuration,
- }));
-
- const otherProcess = model.getOrCreateProcess(3);
- const otherThread = otherProcess.getOrCreateThread(4);
- otherThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
- type: tr.model.ThreadSlice,
- isTopLevel: true,
- start: 0,
- duration: sliceDuration,
- cpuStart: 0,
- cpuDuration: sliceDuration,
- }));
- });
- assert.closeTo(value, 0.05, 0.001);
+ test('threadsAcrossMultipleProcessTypesAggregate', () => {
+ const modelSpec = {
+ processes: [
+ {
+ name: 'Browser',
+ pid: 12345,
+ threads: [
+ {
+ name: 'CrBrowserMain',
+ tid: 1,
+ slices: [],
+ },
+ ],
+ },
+ {
+ name: 'Renderer',
+ pid: 20001,
+ threads: [
+ {
+ name: 'Chrome_ChildIOThread',
+ tid: 42,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 20) {
+ slices.push({range:[i, i + 10], cpu: 5});
+ }
+ return slices;
+ })(),
+ },
+ ],
+ },
+ {
+ name: 'GPU Process',
+ pid: 30001,
+ threads: [
+ {
+ name: 'Chrome_ChildIOThread',
+ tid: 52,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 100) {
+ slices.push({range:[i, i + 80], cpu: 40});
+ }
+ return slices;
+ })(),
+ },
+ ]
+ },
+ ],
+
+ // [Video A] [Click R] [CSS A] [ CSS A ]
+ // [Scroll R]
+ // [Scroll R]
+ expectations: [
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [0, 90]},
+
+ {stage: 'Response', initiatorType: IT.CLICK, range: [200, 220]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [210, 260]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [250, 300]},
+
+
+ {stage: 'Animation', initiatorType: IT.CSS, range: [500, 560]},
+ {stage: 'Animation', initiatorType: IT.CSS, range: [690, 890]},
+ ],
+ };
+
+ const model = buildModelFromSpec(modelSpec);
+ const histograms = new tr.v.HistogramSet();
+ tr.metrics.sh.cpuTimeMetric(histograms, model);
+
+ const subMetricPrefix1 =
+ 'cpuTime:Renderer:Chrome_ChildIOThread';
+ const subMetricPrefix2 =
+ 'cpuTime:GPU:Chrome_ChildIOThread';
+ const aggregateMetricPrefix =
+ 'cpuTime:all_processes:Chrome_ChildIOThread';
+
+ function getMetricValueFromHistogram(histograms, metricName) {
+ return histograms.getHistogramNamed(fixMetricName(metricName)).sum;
+ }
+
+ const metricSuffixes = [
+ // Single expectation range of same initiator type.
+ 'Animation:Video',
+ // Disjoint expectation ranges of same initiator type.
+ 'Animation:CSS',
+ // Overlapping expectation ranges of same initiator type.
+ 'Response:Scroll',
+ // Disjoint expectation ranges with all_initiators.
+ 'Animation:all_initiators',
+ // Overlapping expectation ranges with all_initiators.
+ 'Response:all_initiators',
+ // all_stages and all_initiators.
+ 'all_stages:all_initiators',
+ ]
+
+ for (const suffix of metricSuffixes) {
+ const subMetricName1 = `${subMetricPrefix1}:${suffix}`;
+ const subMetricName2 = `${subMetricPrefix2}:${suffix}`;
+ const aggregateMetricName = `${aggregateMetricPrefix}:${suffix}`;
+ const subMetric1 = getMetricValueFromHistogram(histograms, subMetricName1);
+ const subMetric2 = getMetricValueFromHistogram(histograms, subMetricName2);
+ const aggregateMetric = getMetricValueFromHistogram(histograms,
+ aggregateMetricName);
+ assert.closeTo(aggregateMetric, subMetric1 + subMetric2, EPSILON7,
+ `${subMetricName1} and ${subMetricName2} aggregates to ` +
+ aggregateMetricName);
+ }
+ });
+
+ test('completeAggregation', () => {
+ const modelSpec = {
+ processes: [
+ {
+ name: 'Browser',
+ pid: 12345,
+ threads: [
+ {
+ name: 'CrBrowserMain',
+ tid: 1,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 50) {
+ slices.push({range:[i, i + 50], cpu: 30});
+ }
+ return slices;
+ })(),
+ },
+ ],
+ },
+ {
+ name: 'Renderer',
+ pid: 20001,
+ threads: [
+ {
+ name: 'Chrome_ChildIOThread',
+ tid: 42,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 20) {
+ slices.push({range:[i, i + 10], cpu: 5});
+ }
+ return slices;
+ })(),
+ },
+ ],
+ },
+ {
+ name: 'GPU Process',
+ pid: 30001,
+ threads: [
+ {
+ name: 'Chrome_ChildIOThread',
+ tid: 52,
+ slices: (() => {
+ const slices = [];
+ for (let i = 0; i < 1000; i += 100) {
+ slices.push({range:[i, i + 80], cpu: 40});
+ }
+ return slices;
+ })(),
+ },
+ ]
+ },
+ ],
+
+ // [Video A] [Click R] [CSS A] [ CSS A ]
+ // [Scroll R]
+ // [Scroll R]
+ expectations: [
+ {stage: 'Animation', initiatorType: IT.VIDEO, range: [0, 90]},
+
+ {stage: 'Response', initiatorType: IT.CLICK, range: [200, 220]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [210, 260]},
+ {stage: 'Response', initiatorType: IT.SCROLL, range: [250, 300]},
+
+ {stage: 'Animation', initiatorType: IT.CSS, range: [500, 560]},
+ {stage: 'Animation', initiatorType: IT.CSS, range: [690, 890]},
+ ],
+ };
+
+ const model = buildModelFromSpec(modelSpec);
+ const histograms = new tr.v.HistogramSet();
+ tr.metrics.sh.cpuTimeMetric(histograms, model);
+
+ const metricName =
+ fixMetricName('cpuTime:all_processes:all_threads:all_stages:all_initiators');
+ const histogram = histograms.getHistogramNamed(metricName);
+ const metricValue = histogram.sum;
+
+ assert.closeTo(metricValue, (30 * 20 + 5 * 50 + 40 * 10) / 1000, EPSILON7);
});
});
</script>
« no previous file with comments | « tracing/tracing/metrics/system_health/cpu_time_metric.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698