| <!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> |