blob: 7e22de365503365e1c9db5f72d674c342b1a5f1d [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 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/metrics/system_health/loading_metric.html">
<link rel="import" href="/tracing/value/value_set.html">
<script>
'use strict';
tr.b.unittest.testSuite(function() {
test('timeToFirstContentfulPaint', function() {
var model = tr.c.TestUtils.newModel(function(model) {
var rendererProcess = model.getOrCreateProcess(1);
var mainThread = rendererProcess.getOrCreateThread(2);
mainThread.name = 'CrRendererMain';
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: 'blink.user_timing,rail',
title: 'firstContentfulPaint',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
});
var values = new tr.v.ValueSet();
tr.metrics.sh.loadingMetric(values, model);
var numeric = tr.b.getOnlyElement(values.getValuesNamed(
'timeToFirstContentfulPaint'));
assert.equal(1, numeric.running.count);
assert.equal(800, numeric.running.mean);
});
test('timeToFirstContentfulPaintIgnoringWarmCache', function() {
var model = tr.c.TestUtils.newModel(function(model) {
var rendererProcess = model.getOrCreateProcess(1);
var mainThread = rendererProcess.getOrCreateThread(2);
mainThread.name = 'CrRendererMain';
// warm cache navigation
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.asyncSliceGroup.push(tr.c.TestUtils.newAsyncSliceEx({
cat: 'blink.console',
title: 'telemetry.internal.warmCache.start',
start: 250,
duration: 0.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: 'blink.user_timing,rail',
title: 'firstContentfulPaint',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.asyncSliceGroup.push(tr.c.TestUtils.newAsyncSliceEx({
cat: 'blink.console',
title: 'telemetry.internal.warmCache.end',
start: 1250,
duration: 0.0
}));
// measurement navigation
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 2000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
rendererProcess.objects.addSnapshot('ptr', 'loading', 'FrameLoader', 2100,
{isLoadingMainFrame: true, frame: {id_ref: '0xdeadbeef'},
documentLoaderURL: 'http://example.com'});
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing,rail',
title: 'firstContentfulPaint',
start: 2400,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
});
var values = new tr.v.ValueSet();
tr.metrics.sh.loadingMetric(values, model);
var numeric = tr.b.getOnlyElement(values.getValuesNamed(
'timeToFirstContentfulPaint'));
assert.equal(1, numeric.running.count);
assert.equal(400, numeric.running.mean);
});
test('timeToFirstMeaningfulPaint', function() {
var model = tr.c.TestUtils.newModel(function(model) {
var rendererProcess = model.getOrCreateProcess(1);
var mainThread = rendererProcess.getOrCreateThread(2);
mainThread.name = 'CrRendererMain';
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: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 600,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 1000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
});
var values = new tr.v.ValueSet();
tr.metrics.sh.loadingMetric(values, model);
var numeric = tr.b.getOnlyElement(values.getValuesNamed(
'timeToFirstMeaningfulPaint'));
assert.equal(1, numeric.running.count);
assert.equal(800, numeric.running.mean);
});
test('timeToInteractive', function() {
// Our renderer thread would looks like
//
// * * [ main thread busy ] *
// | | |
// | | |
// v v v
// First navigation FMP TTI
// 200 9200 15400
var model = tr.c.TestUtils.newModel(function(model) {
var rendererProcess = model.getOrCreateProcess(1984);
var mainThread = rendererProcess.getOrCreateThread(2);
mainThread.name = 'CrRendererMain';
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: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 9180,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 9200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 9350,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 11150,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 12550,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 14950,
duration: 500,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 22150,
duration: 10,
}));
});
var values = new tr.v.ValueSet();
tr.metrics.sh.loadingMetric(values, model);
var numeric = tr.b.getOnlyElement(values.getValuesNamed(
'timeToFirstInteractive'));
assert.equal(1, numeric.running.count);
assert.equal(15200, numeric.running.mean);
var binsWithSampleDiagnosticMaps = numeric.allBins.filter(
bin => bin.diagnosticMaps.length > 0);
var diagnostic = binsWithSampleDiagnosticMaps[0].diagnosticMaps[0].get(
'Navigation infos');
assert.equal(diagnostic.value.start, 200);
assert.equal(diagnostic.value.interactive, 15400);
assert.equal(diagnostic.value.pid, 1984);
});
test('multiTimeToInteractive', function() {
// Our renderer thread would looks like
//
// * * [ main thread busy ] * * *
// | | | | |
// | | | | |
// v v v v v
// 1st navigation 1st FMP 2nd nav 1st TTI 2nd FMP & TTI
// 200 9200 12000 14500 16000
var model = tr.c.TestUtils.newModel(function(model) {
var rendererProcess = model.getOrCreateProcess(1984);
var mainThread = rendererProcess.getOrCreateThread(2);
mainThread.name = 'CrRendererMain';
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: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 9180,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 9200,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 9350,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 11150,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'blink.user_timing',
title: 'navigationStart',
start: 12000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 12550,
duration: 100,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 14950,
duration: 500,
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'loading',
title: 'firstMeaningfulPaintCandidate',
start: 16000,
duration: 0.0,
args: {frame: '0xdeadbeef'}
}));
mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
cat: 'toplevel',
title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
start: 29150,
duration: 10,
}));
});
var values = new tr.v.ValueSet();
tr.metrics.sh.loadingMetric(values, model);
var numeric = tr.b.getOnlyElement(values.getValuesNamed(
'timeToFirstInteractive'));
assert.equal(2, numeric.running.count);
assert.equal(4000, numeric.running.min);
assert.equal(15200, numeric.running.max);
});
});
</script>