blob: e11aca5c4f808213c53afa12beb69e761f5c40bb [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright 2019 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/base/utils.html">
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/metrics/uma_metric.html">
<link rel="import" href="/tracing/value/histogram_set.html">
<script>
'use strict';
tr.b.unittest.testSuite(function() {
// 1 sample in [1, 3) and 2 samples in [3, 7).
const BROWSER_BUCKETS =
'LAAAAAwAAAAAAAAAAwAAAAEAAAADAAAAAAAAAAEAAAADAAAABwAAAAAAAAACAAAA';
// 1 sample in [3, 7).
const RENDERER_BUCKETS = 'HAAAABAAAAAAAAAAAgAAAAcAAAAJAAAAAAAAAAIAAAA=';
// 2 samples in [8, 10).
const RENDERER_INCOMPATIBLE_BUCKETS =
'HAAAAAkAAAAAAAAAAQAAAAgAAAAKAAAAAAAAAAEAAAA=';
// 1 sample in [1, 3) and 2 samples in [3, 7). The sum is 9.
const SHIFTED_SAMPLES =
'LAAAAAkAAAAAAAAAAwAAAAEAAAADAAAAAAAAAAEAAAADAAAABwAAAAAAAAACAAAA';
// 50 samples in [2^30, 2^30 + 2).
const LARGE_SUM = 'HAAAADIAAIAMAAAAMgAAAAAAAEACAABAAAAAADIAAAA=';
test('simpleUMA', function() {
const model = tr.c.TestUtils.newModel((model) => {
const browserProcess = model.getOrCreateProcess(0);
browserProcess.getOrCreateThread(0).name = 'CrBrowserMain';
browserProcess.instantEvents.push(tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: BROWSER_BUCKETS}}));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.umaMetric(histograms, model);
const hist = histograms.getHistogramNamed('metric1');
// The histogram looks like:
// *
// * *
// 1 2 3 4 5 6 7
assert.closeTo(2, hist.min, 1e-6);
assert.closeTo(5, hist.max, 1e-6);
assert.closeTo(4, hist.average, 1e-6);
const bin = hist.getBinForValue(2);
const processes = tr.b.getOnlyElement(bin.diagnosticMaps).get('processes');
assert.closeTo(2, processes.get('browser_process_1'), 1e-6);
});
test('twoUMASnapshotsInDifferentProcesses', function() {
const model = tr.c.TestUtils.newModel((model) => {
const browserProcess = model.getOrCreateProcess(0);
browserProcess.getOrCreateThread(0).name = 'CrBrowserMain';
browserProcess.instantEvents.push(tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: BROWSER_BUCKETS}}));
const process = model.getOrCreateProcess(1);
process.instantEvents.push(tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: RENDERER_BUCKETS}}));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.umaMetric(histograms, model);
const hist = histograms.getHistogramNamed('metric1');
// The aggregated histogram looks like
// * *
// * * *
// 1 2 3 4 5 6 7 8 9
assert.closeTo(2, hist.min, 1e-6);
assert.closeTo(8, hist.max, 1e-6);
assert.closeTo(5.6, hist.average, 1e-6);
const bin = hist.getBinForValue(8);
for (const diagnostics of bin.diagnosticMaps) {
assert.closeTo(
8, diagnostics.get('processes').get('unknown_processes_1'), 1e-6);
}
});
test('samplesNotInTheMiddle', function() {
const model = tr.c.TestUtils.newModel((model) => {
const browserProcess = model.getOrCreateProcess(0);
browserProcess.getOrCreateThread(0).name = 'CrBrowserMain';
browserProcess.instantEvents.push(tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: SHIFTED_SAMPLES}}));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.umaMetric(histograms, model);
const hist = histograms.getHistogramNamed('metric1');
// There is 1 sample in [1, 3) and 2 samples in [3, 7). Since the sum is 9,
// we put samples lower than the middle of the bins so that they sum to 9.
assert.closeTo(1.4, hist.min, 1e-6);
assert.closeTo(3.8, hist.max, 1e-6);
assert.closeTo(3, hist.average, 1e-6);
});
test('largeSampleSum', function() {
const model = tr.c.TestUtils.newModel((model) => {
const browserProcess = model.getOrCreateProcess(0);
browserProcess.getOrCreateThread(0).name = 'CrBrowserMain';
browserProcess.instantEvents.push(tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: LARGE_SUM}}));
});
const histograms = new tr.v.HistogramSet();
tr.metrics.umaMetric(histograms, model);
const hist = histograms.getHistogramNamed('metric1');
assert.closeTo((1 << 30) + 1, hist.min, 1e-6);
assert.closeTo((1 << 30) + 1, hist.max, 1e-6);
assert.closeTo(((1 << 30) + 1) * 50, hist.sum, 1e-6);
});
test('incompatibleUMASnapshots', function() {
const model = tr.c.TestUtils.newModel((model) => {
model.getOrCreateProcess(0).getOrCreateThread(0).name = 'CrBrowserMain';
model.getOrCreateProcess(1).instantEvents.push(
tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: RENDERER_BUCKETS}})
);
model.getOrCreateProcess(2).instantEvents.push(
tr.c.TestUtils.newInstantEvent({
title: 'UMAHistogramSamples', start: 2,
args: {
name: 'metric1',
buckets: RENDERER_INCOMPATIBLE_BUCKETS}})
);
});
const histograms = new tr.v.HistogramSet();
assert.throws(function() {
tr.metrics.umaMetric(histograms, model);
}, 'Incompatible bins');
});
});
</script>