blob: 2862c14ce6d4d8d89d4b6fc692fddc4b1d68c5c6 [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/base/utils.html">
<link rel="import" href="/tracing/ui/base/deep_utils.html">
<link rel="import" href="/tracing/value/histogram.html">
<link rel="import" href="/tracing/value/ui/value_set_table.html">
<link rel="import" href="/tracing/value/value_set.html">
<script>
'use strict';
tr.b.unittest.testSuite(function() {
var TEST_BOUNDARIES = tr.v.HistogramBinBoundaries.createLinear(0, 1e3, 20);
function getTableRowAtPath(table, path) {
var row = table.tableRows[0];
for (var index of path)
row = row.subRows[index];
return row;
}
// TODO(benjhayden): Test requestSelectionChange.
// TODO(benjhayden): Test search keyup.
// TODO(benjhayden): Test referenceDisplayLabel.
test('implicitUndefinedValues', function() {
var table = document.createElement('tr-v-ui-value-set-table');
this.addHTMLOutput(table);
assert.strictEqual('block', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === 'zero values')).display);
assert.strictEqual('none', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.id === 'container')).display);
});
test('explicitUndefinedValues', function() {
var table = document.createElement('tr-v-ui-value-set-table');
table.values = undefined;
this.addHTMLOutput(table);
assert.strictEqual('block', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === 'zero values')).display);
assert.strictEqual('none', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.id === 'container')).display);
});
test('emptyValues', function() {
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
table.values = values;
this.addHTMLOutput(table);
assert.strictEqual('block', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === 'zero values')).display);
assert.strictEqual('none', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.id === 'container')).display);
});
test('shortName', function() {
// One value has |name|='long name' and |shortName|='short name',
// another value has |name|='short name' to demonstrate the fundamental
// ambiguity that arises when Values can have multiple different "names".
var now = new Date().getTime();
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
var histA = new tr.v.Histogram('long name',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
histA.addSample(Math.random() * 1e3);
histA.shortName = 'short name';
new tr.v.d.IterationInfo({
label: 'iteration A',
benchmarkStartMs: now,
}).addToValue(histA);
values.addHistogram(histA);
var histB = new tr.v.Histogram('short name',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
histB.addSample(Math.random() * 1e3);
new tr.v.d.IterationInfo({
label: 'iteration B',
benchmarkStartMs: now,
}).addToValue(histB);
values.addHistogram(histB);
table.values = values;
this.addHTMLOutput(table);
assert.strictEqual('none', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === 'zero values')).display);
assert.strictEqual('block', getComputedStyle(
tr.b.findDeepElementMatchingPredicate(
table, e => e.id === 'container')).display);
assert.isDefined(tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === 'short name'));
assert.isUndefined(tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === 'long name'));
});
test('emptyAndMissing', function() {
var now = new Date().getTime();
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
var histA = new tr.v.Histogram('histogram A',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
histA.addSample(Math.random() * 1e3);
new tr.v.d.IterationInfo({
label: 'iteration A',
benchmarkStartMs: now,
}).addToValue(histA);
values.addHistogram(histA);
var histB = new tr.v.Histogram('histogram B',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
histB.addSample(Math.random() * 1e3);
new tr.v.d.IterationInfo({
label: 'iteration B',
benchmarkStartMs: now,
}).addToValue(histB);
values.addHistogram(histB);
var histC = new tr.v.Histogram('histogram A',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
new tr.v.d.IterationInfo({
label: 'iteration B',
benchmarkStartMs: now,
}).addToValue(histC);
values.addHistogram(histC);
table.values = values;
this.addHTMLOutput(table);
assert.isDefined(tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === '(empty)'));
assert.isDefined(tr.b.findDeepElementMatchingPredicate(
table, e => e.textContent === '(missing)'));
});
test('instantiate_1x1', function() {
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
var hist = new tr.v.Histogram('foo',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
hist.addSample(Math.random() * 1e3);
values.addHistogram(hist);
table.values = values;
this.addHTMLOutput(table);
var baseTable = tr.b.findDeepElementMatchingPredicate(
table, elem => elem.tagName === 'TR-UI-B-TABLE');
assert.strictEqual(baseTable.tableRows.length, 1);
});
test('merge_unmergeable', function() {
var now = new Date().getTime();
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
var histA = new tr.v.Histogram('histogram A',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
histA.addSample(Math.random() * 1e3);
new tr.v.d.IterationInfo({
label: 'Value',
benchmarkStartMs: now,
storyDisplayName: 'story A'
}).addToValue(histA);
values.addHistogram(histA);
var histB = new tr.v.Histogram('histogram B',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,
tr.v.HistogramBinBoundaries.createExponential(1e-3, 1e3, 20));
for (var i = 0; i < 100; ++i)
histB.addSample(Math.random() * Math.random() * 1e3);
new tr.v.d.IterationInfo({
label: 'Value',
benchmarkStartMs: now,
storyDisplayName: 'story A'
}).addToValue(histB);
values.addHistogram(histB);
var histC = new tr.v.Histogram('histogram C',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,
tr.v.HistogramBinBoundaries.createExponential(1e-3, 1e3, 30));
for (var i = 0; i < 100; ++i)
histC.addSample(Math.random() * Math.random() * 1e3);
new tr.v.d.IterationInfo({
label: 'Value',
benchmarkStartMs: now,
storyDisplayName: 'story B'
}).addToValue(histC);
values.addHistogram(histC);
table.values = values;
table.groupingKeys = [tr.v.ValueSet.GROUPINGS.STORY_NAME.key];
this.addHTMLOutput(table);
var baseTable = tr.b.findDeepElementMatchingPredicate(
table, elem => elem.tagName === 'TR-UI-B-TABLE');
assert.strictEqual(baseTable.tableRows.length, 2);
});
test('instantiate_2x2', function() {
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
var numeric0a = new tr.v.Histogram('foo',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
numeric0a.addSample(Math.random() * 1e3);
values.addHistogram(numeric0a);
new tr.v.d.IterationInfo({
label: 'iteration A',
benchmarkStartMs: new Date().getTime(),
}).addToValue(numeric0a);
var numeric1a = new tr.v.Histogram('bar',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
numeric1a.addSample(Math.random() * 1e3);
values.addHistogram(numeric1a);
new tr.v.d.IterationInfo({
label: 'iteration A',
benchmarkStartMs: new Date().getTime(),
}).addToValue(numeric1a);
var numeric0b = new tr.v.Histogram('foo',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
numeric0b.addSample(Math.random() * 1e3);
values.addHistogram(numeric0b);
new tr.v.d.IterationInfo({
label: 'iteration B',
benchmarkStartMs: new Date().getTime(),
}).addToValue(numeric0b);
var numeric1b = new tr.v.Histogram('bar',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
numeric1b.addSample(Math.random() * 1e3);
values.addHistogram(numeric1b);
new tr.v.d.IterationInfo({
label: 'iteration B',
benchmarkStartMs: new Date().getTime(),
}).addToValue(numeric1b);
table.values = values;
this.addHTMLOutput(table);
var baseTable = tr.b.findDeepElementMatchingPredicate(
table, elem => elem.tagName === 'TR-UI-B-TABLE');
assert.lengthOf(baseTable.tableColumns, 3);
assert.strictEqual('Name', baseTable.tableColumns[0].title);
assert.strictEqual('iteration A', baseTable.tableColumns[1].title);
assert.strictEqual('iteration B', baseTable.tableColumns[2].title);
});
test('instantiation_mergeNumerics', function() {
var table = document.createElement('tr-v-ui-value-set-table');
var values = new tr.v.ValueSet();
// Add 64 Histograms, all named 'foo', with different IterationInfos.
var benchmarkNames = ['bm A', 'bm B'];
var storyGroupingKeys0 = ['A', 'B'];
var storyGroupingKeys1 = ['C', 'D'];
var storyNames = ['story A', 'story B'];
var starts = [1439708400000, 1439794800000];
var labels = ['label A', 'label B'];
for (var benchmarkName of benchmarkNames) {
for (var storyGroupingKey0 of storyGroupingKeys0) {
for (var storyGroupingKey1 of storyGroupingKeys1) {
for (var storyName of storyNames) {
for (var startMs of starts) {
for (var storysetCounter = 0; storysetCounter < 2;
++storysetCounter) {
for (var storyCounter = 0; storyCounter < 2; ++storyCounter) {
for (var label of labels) {
var numeric = new tr.v.Histogram('foo',
tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,
TEST_BOUNDARIES);
for (var i = 0; i < 100; ++i)
numeric.addSample(Math.random() * 1e3);
values.addHistogram(numeric);
new tr.v.d.IterationInfo({
storyGroupingKeys: {
storyGroupingKey0: storyGroupingKey0,
storyGroupingKey1: storyGroupingKey1
},
benchmarkName: benchmarkName,
storyDisplayName: storyName,
benchmarkStartMs: startMs,
storysetRepeatCounter: storysetCounter,
storyRepeatCounter: storyCounter,
label: label,
}).addToValue(numeric);
}
}
}
}
}
}
}
}
table.values = values;
table.groupingKeys = [
tr.v.ValueSet.GROUPINGS.HISTOGRAM_NAME.key,
tr.v.ValueSet.GROUPINGS.BENCHMARK_NAME.key,
'storyGroupingKey_storyGroupingKey0',
'storyGroupingKey_storyGroupingKey1',
tr.v.ValueSet.GROUPINGS.STORY_NAME.key,
tr.v.ValueSet.GROUPINGS.BENCHMARK_START.key,
tr.v.ValueSet.GROUPINGS.STORYSET_REPEAT.key,
tr.v.ValueSet.GROUPINGS.STORY_REPEAT.key,
];
this.addHTMLOutput(table);
var baseTable = tr.b.findDeepElementMatchingPredicate(
table, elem => elem.tagName === 'TR-UI-B-TABLE');
assert.lengthOf(baseTable.tableColumns, 3);
assert.strictEqual('Name', baseTable.tableColumns[0].title);
assert.strictEqual('label A', baseTable.tableColumns[1].title);
assert.strictEqual('label B', baseTable.tableColumns[2].title);
assert.lengthOf(baseTable.tableRows, 1);
assert.strictEqual('foo', baseTable.tableRows[0].name);
assert.lengthOf(baseTable.tableRows[0].subRows, 2);
// assertions only report their arguments, which is not enough information
// to diagnose problems with nested structures like tableRows -- the path to
// the particular row is needed. This code would be a bit simpler if each
// row were given a named variable, but the path to each subRow would still
// need to be tracked in order to provide for diagnosing.
var subRowPath = [];
var getSubRow = () => getTableRowAtPath(baseTable, subRowPath);
for (var i = 0; i < benchmarkNames.length; ++i) {
subRowPath.push(i);
assert.lengthOf(getSubRow().subRows, 2, subRowPath);
assert.strictEqual(benchmarkNames[i], getSubRow().name, subRowPath);
for (var s = 0; s < storyGroupingKeys0.length; ++s) {
subRowPath.push(s);
assert.lengthOf(getSubRow().subRows, 2, subRowPath);
assert.strictEqual('storyGroupingKey0: ' + storyGroupingKeys0[s],
getSubRow().name, subRowPath);
for (var t = 0; t < storyGroupingKeys1.length; ++t) {
subRowPath.push(t);
assert.lengthOf(getSubRow().subRows, 2, subRowPath);
assert.strictEqual('storyGroupingKey1: ' + storyGroupingKeys1[t],
getSubRow().name, subRowPath);
for (var j = 0; j < storyNames.length; ++j) {
subRowPath.push(j);
assert.lengthOf(getSubRow().subRows, 2, subRowPath);
assert.strictEqual(storyNames[j], getSubRow().name, subRowPath);
for (var k = 0; k < starts.length; ++k) {
subRowPath.push(k);
assert.lengthOf(getSubRow().subRows, 2, subRowPath);
assert.strictEqual(tr.b.formatDate(new Date(starts[k])),
getSubRow().name, subRowPath);
for (var l = 0; l < 2; ++l) {
subRowPath.push(l);
assert.lengthOf(getSubRow().subRows, 2, subRowPath);
assert.strictEqual('storyset repeat ' + l, getSubRow().name,
subRowPath);
for (var m = 0; m < 2; ++m) {
subRowPath.push(m);
assert.lengthOf(getSubRow().subRows, 1, subRowPath);
assert.strictEqual('story repeat ' + m, getSubRow().name,
subRowPath);
subRowPath.push(0);
assert.strictEqual('iteration', getSubRow().name, subRowPath);
subRowPath.pop();
subRowPath.pop();
}
subRowPath.pop();
}
subRowPath.pop();
}
subRowPath.pop();
}
subRowPath.pop();
}
subRowPath.pop();
}
subRowPath.pop();
}
});
});
</script>