blob: 3db10c8e413d5b94e8a6263bee7708f59d9b0b2b [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2013 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="/base/task.html">
<link rel="import" href="/core/test_utils.html">
<link rel="import" href="/core/timeline_track_view.html">
<link rel="import" href="/extras/importer/trace_event_importer.html">
<script>
'use strict';
tv.b.unittest.testSuite(function() {
var Selection = tv.c.Selection;
var SelectionState = tv.c.trace_model.SelectionState;
var Task = tv.b.Task;
function contains(array, element) {
for (var i = 0; i < array.length; i++) {
if (array[i] === element) {
return true;
}
}
return false;
};
function checkSelectionStates(timeline, selection, highlight) {
selection = selection || [];
highlight = highlight || [];
// The objects timeline.selection and timeline.highlight are not actually
// Arrays, they are Selection objects. Here we are not checking the other
// properties of the selection and highlight, only the numbered properties.
assert.equal(timeline.selection.length, selection.length);
assert.equal(timeline.highlight.length, highlight.length);
for (var i = 0; i < selection.length; i++)
assert.strictEqual(timeline.selection[i], selection[i]);
for (var i = 0; i < highlight.length; i++)
assert.strictEqual(timeline.highlight[i], highlight[i]);
timeline.model.iterateAllEvents(function(event) {
if (contains(selection, event))
assert.equal(event.selectionState, SelectionState.SELECTED);
else if (contains(highlight, event))
assert.equal(event.selectionState, SelectionState.HIGHLIGHTED);
else if (highlight.length)
assert.equal(event.selectionState, SelectionState.DIMMED);
else
assert.equal(event.selectionState, SelectionState.NONE);
});
};
test('instantiate', function() {
var model = new tv.c.TraceModel();
var num_threads = 500;
model.importTraces([], false, false, function() {
var p100 = model.getOrCreateProcess(100);
for (var i = 0; i < num_threads; i++) {
var t = p100.getOrCreateThread(101 + i);
if (i % 2 == 0) {
t.sliceGroup.beginSlice('cat', 'a', 100);
t.sliceGroup.endSlice(110);
} else {
t.sliceGroup.beginSlice('cat', 'b', 50);
t.sliceGroup.endSlice(120);
}
}
});
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
timeline.focusElement = timeline;
timeline.tabIndex = 0;
timeline.style.maxHeight = '600px';
this.addHTMLOutput(timeline);
});
test('addAllObjectsMatchingFilterToSelectionAsTask', function() {
var model = new tv.c.TraceModel();
var p1 = model.getOrCreateProcess(1);
var t1 = p1.getOrCreateThread(1);
t1.sliceGroup.pushSlice(
new tv.c.trace_model.ThreadSlice('', 'a', 0, 1, {}, 3));
t1.sliceGroup.pushSlice(
new tv.c.trace_model.ThreadSlice('', 'b', 0, 1.1, {}, 2.8));
var t1asg = t1.asyncSliceGroup;
t1asg.slices.push(
tv.c.test_utils.newAsyncSliceNamed('a', 0, 1, t1, t1));
t1asg.slices.push(
tv.c.test_utils.newAsyncSliceNamed('b', 1, 2, t1, t1));
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
var expected = [t1asg.slices[0],
t1.sliceGroup.slices[0]];
var result = new tv.c.Selection();
var filterTask = timeline.addAllObjectsMatchingFilterToSelectionAsTask(
new tv.c.TitleOrCategoryFilter('a'), result);
Task.RunSynchronously(filterTask);
assert.equal(result.length, 2);
assert.equal(result[0], expected[0]);
assert.equal(result[1], expected[1]);
var expected = [t1asg.slices[1],
t1.sliceGroup.slices[1]];
var result = new tv.c.Selection();
var filterTask = timeline.addAllObjectsMatchingFilterToSelectionAsTask(
new tv.c.TitleOrCategoryFilter('b'), result);
Task.RunSynchronously(filterTask);
assert.equal(result.length, 2);
assert.equal(result[0], expected[0]);
assert.equal(result[1], expected[1]);
});
test('emptyThreadsDeleted', function() {
var model = new tv.c.TraceModel();
var p1 = model.getOrCreateProcess(1);
var t1 = p1.getOrCreateThread(1);
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
assert.isFalse(timeline.hasVisibleContent);
});
test('filteredCounters', function() {
var model = new tv.c.TraceModel();
var c1 = model.kernel.getOrCreateCpu(0);
c1.getOrCreateCounter('', 'b');
var p1 = model.getOrCreateProcess(1);
var ctr = p1.getOrCreateCounter('', 'a');
var series = new tv.c.trace_model.CounterSeries('a', 0);
series.addCounterSample(0, 1);
ctr.addSeries(series);
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
assert.isTrue(timeline.hasVisibleContent);
});
test('filteredCpus', function() {
var model = new tv.c.TraceModel();
var c1 = model.kernel.getOrCreateCpu(1);
c1.getOrCreateCounter('', 'a');
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
assert.isTrue(timeline.hasVisibleContent);
});
test('filteredProcesses', function() {
var model = new tv.c.TraceModel();
var p1 = model.getOrCreateProcess(1);
p1.getOrCreateCounter('', 'a');
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
assert.isTrue(timeline.hasVisibleContent);
});
test('filteredThreads', function() {
var model = new tv.c.TraceModel();
var p1 = model.getOrCreateProcess(1);
var t1 = p1.getOrCreateThread(2);
t1.sliceGroup.pushSlice(tv.c.test_utils.newSlice(0, 1));
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
assert.isTrue(timeline.hasVisibleContent);
});
test('selectionAndHighlight', function() {
var events = [
{name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
{name: 'a', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'ab', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'b', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'B'},
{name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'B'}
];
var model = new tv.c.TraceModel(events);
var timeline = new tv.c.TimelineTrackView();
timeline.model = model;
var selection = new Selection();
var filterTask = timeline.addAllObjectsMatchingFilterToSelectionAsTask(
new tv.c.TitleOrCategoryFilter('a'), selection);
Task.RunSynchronously(filterTask);
var highlight = new Selection();
var filterTask = timeline.addAllObjectsMatchingFilterToSelectionAsTask(
new tv.c.TitleOrCategoryFilter('b'), highlight);
Task.RunSynchronously(filterTask);
// Test for faulty input.
assert.throw(function() {
timeline.selection = 'selection';
});
assert.throw(function() {
timeline.highlight = 1;
});
assert.throw(function() {
timeline.setSelectionAndHighlight(0, false);
});
// Check state after reset.
timeline.setSelectionAndHighlight(null, null);
checkSelectionStates(timeline, null, null);
// Add selection only.
timeline.selection = selection;
assert.equal(timeline.selection, selection);
checkSelectionStates(timeline, selection, null);
// Reset selection.
timeline.selection = null;
assert.equal(timeline.selection.length, 0);
checkSelectionStates(timeline, null, null);
// Add highlight only.
timeline.highlight = highlight;
assert.equal(timeline.highlight, highlight);
checkSelectionStates(timeline, null, highlight);
// Reset highlight
timeline.highlight = null;
assert.equal(timeline.highlight.length, 0);
checkSelectionStates(timeline, null, null);
// Add selection and highlight.
timeline.setSelectionAndHighlight(selection, highlight);
checkSelectionStates(timeline, selection, highlight);
// Selection replaces old selection.
var subSelection = selection.subSelection(0, 1);
timeline.selection = subSelection;
checkSelectionStates(timeline, subSelection, highlight);
// Highlight replaces old highlight.
var subHighlight = highlight.subSelection(1, 2);
timeline.highlight = subHighlight;
checkSelectionStates(timeline, subSelection, subHighlight);
// Set selection and clear highlight.
timeline.setSelectionAndClearHighlight(selection);
checkSelectionStates(timeline, selection, null);
// Set highlight and clear selection.
timeline.setHighlightAndClearSelection(highlight);
checkSelectionStates(timeline, null, highlight);
// Reset both.
timeline.setSelectionAndHighlight(null, null);
checkSelectionStates(timeline, null, null);
});
test('interestRange', function() {
var events = [
{name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
{name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'c', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'c', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'E'},
{name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'},
{name: 'a', args: {}, pid: 52, ts: 634, cat: 'foo', tid: 53, ph: 'E'}
];
var model = new tv.c.TraceModel(events);
var trackView = new tv.c.TimelineTrackView();
trackView.model = model;
this.addHTMLOutput(trackView);
var slice = model.processes[52].threads[53].sliceGroup.slices[2];
trackView.viewport.interestRange.setMinAndMax(slice.start, slice.end);
});
test('emptyInterestRange', function() {
var events = [
{name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
{name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'c', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'c', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'E'},
{name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'},
{name: 'a', args: {}, pid: 52, ts: 634, cat: 'foo', tid: 53, ph: 'E'}
];
var model = new tv.c.TraceModel(events);
var trackView = new tv.c.TimelineTrackView();
trackView.model = model;
this.addHTMLOutput(trackView);
trackView.viewport.interestRange.reset();
});
test('thinnestInterestRange', function() {
var events = [
{name: 'a', args: {}, pid: 52, ts: 520, cat: 'foo', tid: 53, ph: 'B'},
{name: 'b', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'c', args: {}, pid: 52, ts: 560, cat: 'foo', tid: 53, ph: 'B'},
{name: 'c', args: {}, pid: 52, ts: 629, cat: 'foo', tid: 53, ph: 'E'},
{name: 'b', args: {}, pid: 52, ts: 631, cat: 'foo', tid: 53, ph: 'E'},
{name: 'a', args: {}, pid: 52, ts: 634, cat: 'foo', tid: 53, ph: 'E'}
];
var model = new tv.c.TraceModel(events);
var trackView = new tv.c.TimelineTrackView();
trackView.model = model;
this.addHTMLOutput(trackView);
trackView.viewport.interestRange.reset();
var slice = model.processes[52].threads[53].sliceGroup.slices[2];
trackView.viewport.interestRange.setMinAndMax(slice.start, slice.start);
});
});
</script>