blob: 77217ac6a3880c5947e232591f22768de29e1ae2 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
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/chrome_user_friendly_category_driver.html">
<link rel="import" href="/tracing/importer/find_input_expectations.html">
<link rel="import" href="/tracing/metrics/system_health/power_metric.html">
<link rel="import" href="/tracing/model/user_model/idle_expectation.html">
<link rel="import" href="/tracing/model/user_model/load_expectation.html">
<link rel="import" href="/tracing/model/user_model/user_expectation.html">
<link rel="import" href="/tracing/value/histogram_set.html">
<script>
'use strict';
function containsData(histograms, name) {
for (const value of histograms) {
if (value.name === name) {
return (value.running !== undefined);
}
}
return undefined;
}
function getMetricValueCount(histograms, name) {
for (const value of histograms) {
if (value.name === name && value.running !== undefined) {
return value.running.count;
}
}
return undefined;
}
function getMetricValueSum(histograms, name) {
for (const value of histograms) {
if (value.name === name && value.running !== undefined) {
return value.running.sum;
}
}
return undefined;
}
function getMetricValueMin(histograms, name) {
for (const value of histograms) {
if (value.name === name && value.running !== undefined) {
return value.running.min;
}
}
return undefined;
}
function getMetricValueAvg(histograms, name) {
for (const value of histograms) {
if (value.name === name && value.running !== undefined) {
return value.running.mean;
}
}
return undefined;
}
function getMetricValueMax(histograms, name) {
for (const value of histograms) {
if (value.name === name && value.running !== undefined) {
return value.running.max;
}
}
return undefined;
}
tr.b.unittest.testSuite(function() {
test('powerMetric_computesChromeBoundsCorrectly', function() {
// Tests if Chrome bounds are computed correctly when there
// are both browser and renderer threads in the trace.
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const rendererThread = model.rendererMain;
const browserProcess = model.browserProcess;
const browserThread = model.browserMain;
rendererThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 200.0,
duration: 500.0,
args: {frame: '0xdeadbeef'}
}));
browserThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000.0,
duration: 500.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 2000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 0, 2000));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueMin(histograms, 'idle:power'), 200.0, .01);
assert.closeTo(getMetricValueAvg(histograms, 'idle:power'), 849.5, .01);
assert.closeTo(getMetricValueMax(histograms, 'idle:power'), 1499.0, .01);
});
test('powerMetric_noPowerSeries', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.lengthOf(histograms, 0);
});
test('powerMetric_emptyPowerSeries', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.lengthOf(histograms, 0);
});
test('powerMetric_noChromeTrace', function() {
const model = tr.c.TestUtils.newModel(function(model) {
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
// Only the whole trace power metric should contain data.
assert(containsData(histograms, 'story:power'));
assert(!containsData(histograms, 'load:energy'));
assert(!containsData(histograms, 'after_load:power'));
});
test('powerMetric_emptyChromeTrace', function() {
const histograms = new tr.v.HistogramSet();
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.LoadExpectation(
model, tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 500));
});
tr.metrics.sh.powerMetric(histograms, model);
assert(containsData(histograms, 'story:power'));
assert(!containsData(histograms, 'load:energy'));
assert(!containsData(histograms, 'after_load:power'));
});
test('powerMetric_powerSeriesStartsLate', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 300; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.LoadExpectation(
model, tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 500));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert(containsData(histograms, 'story:power'));
assert(!containsData(histograms, 'load:energy'));
assert(!containsData(histograms, 'after_load:power'));
});
test('powerMetric_powerSeriesEndsEarly', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 700; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.LoadExpectation(
model, tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 500));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert(containsData(histograms, 'story:power'));
assert(!containsData(histograms, 'load:energy'));
assert(!containsData(histograms, 'after_load:power'));
});
test('powerMetric_generic_oneStageEachType_irBeyondChrome', function() {
const model = tr.c.TestUtils.newModel(function(model) {
const rendererProcess = model.getOrCreateProcess(1234);
const mainThread = rendererProcess.getOrCreateThread(1);
mainThread.name = 'CrRendererMain';
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.ResponseExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 1500));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueSum(histograms,
'scroll_response:energy'), 125, 0.5);
assert.closeTo(getMetricValueAvg(histograms,
'idle:power'), 750, 0.5);
assert.closeTo(getMetricValueAvg(histograms,
'story:power'), 500, 0.5);
});
test('powerMetric_story_minAvgMax', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.ResponseExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 1500));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueMin(histograms, 'story:power'), 0, .01);
assert.closeTo(getMetricValueAvg(histograms, 'story:power'), 500, .01);
assert.closeTo(getMetricValueMax(histograms, 'story:power'), 1000, .01);
});
test('powerMetric_generic_oneUEBeforeChrome', function() {
const model = tr.c.TestUtils.newModel(function(model) {
const rendererProcess = model.getOrCreateProcess(1234);
const mainThread = rendererProcess.getOrCreateThread(1);
mainThread.name = 'CrRendererMain';
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 500,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 0, 300));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 300, 1000));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueAvg(histograms,
'idle:power'), 750, 0.5);
});
test('powerMetric_generic_multipleStagesEachType', function() {
const model = tr.c.TestUtils.newModel(function(model) {
const rendererProcess = model.getOrCreateProcess(1234);
const mainThread = rendererProcess.getOrCreateThread(1);
mainThread.name = 'CrRendererMain';
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.ResponseExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 0, 200));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 200, 300));
model.userModel.expectations.push(new tr.model.um.ResponseExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 500, 400));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 900, 100));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueSum(histograms,
'scroll_response:energy'), 300, 0.6);
assert.closeTo(getMetricValueAvg(histograms,
'idle:power'), 500, 0.6);
assert.strictEqual(getMetricValueCount(histograms,
'scroll_response:energy'), 2);
assert.strictEqual(getMetricValueCount(histograms,
'idle:power'), 400);
});
test('powerMetric_loading_oneInterval_samplesBeyondChrome', function() {
// Interval of load is [200, 15400].
// Trace goes until 22150.
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.rendererMain.asyncSliceGroup.push(tr.c.TestUtils.newSliceEx({
cat: 'disabled-by-default-network',
title: 'ResourceLoad',
start: 200,
duration: 5.0
}));
rendererProcess.objects.addSnapshot('ptr', 'loading', 'FrameLoader', 300,
{isLoadingMainFrame: true, frame: {id_ref: '0xdeadbeef'},
documentLoaderURL: 'http://example.com'});
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'loading',
title: 'firstContentfulPaint',
start: 9200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'domContentLoadedEventEnd',
start: 9200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 9350,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 11150,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 12550,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 14900,
duration: 500,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 22150,
duration: 10,
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 15400; i++) {
model.device.powerSeries.addPowerSample(i, 20);
}
for (let i = 15401; i <= 22160; i++) {
model.device.powerSeries.addPowerSample(i, 10);
}
for (let i = 22160; i <= 30000; i++) {
model.device.powerSeries.addPowerSample(i, 10);
}
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
// Energy for first load is 20 W * 15.2 s
// (interval from 0.2 s to 15.4 s)
assert.closeTo(
getMetricValueAvg(histograms, 'load:energy'), 304, 0.1);
});
test('powerMetric_loading_noMeaningfulPaint', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
rendererProcess.objects.addSnapshot('ptr', 'loading', 'FrameLoader', 300,
{isLoadingMainFrame: true, frame: {id_ref: '0xdeadbeef'},
documentLoaderURL: 'http://example.com'});
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 9350,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 11150,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 12550,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 14950,
duration: 500,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: tr.e.chrome.SCHEDULER_TOP_LEVEL_TASK_TITLE,
start: 22150,
duration: 10,
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 15400; i++) {
model.device.powerSeries.addPowerSample(i, 20);
}
for (let i = 15401; i <= 22160; i++) {
model.device.powerSeries.addPowerSample(i, 10);
}
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
// Energy for first load is 20 W * 15.2 s
// (interval from 0.2 s to 15.4 s)
assert.isUndefined(getMetricValueCount(histograms, 'after_load:power'));
});
test('powerMetric_scroll_oneStageEachType', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.AnimationExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 500));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueAvg(histograms,
'scroll_animation:power'), 250, 0.5);
});
test('powerMetric_scroll_multipleStagesEachType', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.AnimationExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 0, 200));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 200, 300));
model.userModel.expectations.push(new tr.model.um.AnimationExpectation(
model, tr.model.um.INITIATOR_TYPE.SCROLL, 500, 200));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 700, 300));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueAvg(histograms,
'scroll_animation:power'), 350, 0.6);
});
test('powerMetric_video_oneStageEachType', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.AnimationExpectation(
model, tr.model.um.INITIATOR_TYPE.VIDEO, 0, 500));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 500, 500));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueAvg(histograms, 'video_animation:power'),
250, 0.5);
});
test('powerMetric_video_multipleStagesEachType', function() {
const model = tr.e.chrome.ChromeTestUtils.newChromeModel(function(model) {
const rendererProcess = model.rendererProcess;
const mainThread = model.rendererMain;
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 0,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
model.device.powerSeries = new tr.model.PowerSeries(model.device);
for (let i = 0; i <= 1000; i++) {
model.device.powerSeries.addPowerSample(i, i);
}
model.userModel.expectations.push(new tr.model.um.AnimationExpectation(
model, tr.model.um.INITIATOR_TYPE.VIDEO, 0, 200));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 200, 300));
model.userModel.expectations.push(new tr.model.um.AnimationExpectation(
model, tr.model.um.INITIATOR_TYPE.VIDEO, 500, 200));
model.userModel.expectations.push(new tr.model.um.IdleExpectation(
model, 700, 300));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.sh.powerMetric(histograms, model);
assert.closeTo(getMetricValueAvg(histograms, 'video_animation:power'),
350, 0.6);
});
});
</script>