Commit c635a663 authored by nduca@chromium.org's avatar nduca@chromium.org

Add TRACE_COUNTER support to about:tracing with dramatically improved test coverage.

Review URL: http://codereview.chromium.org/8513009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110671 0039d316-1c4b-4281-b951-d872f2087c98
parent 01172831
......@@ -46,10 +46,8 @@ cr.define('tracing', function() {
this.timelineView_ = new TimelineView();
this.controlDiv_.appendChild(this.recordBn_);
if (!browserBridge.debugMode) {
this.controlDiv_.appendChild(this.loadBn_);
this.controlDiv_.appendChild(this.saveBn_);
}
this.controlDiv_.appendChild(this.loadBn_);
this.controlDiv_.appendChild(this.saveBn_);
this.container_.appendChild(this.timelineView_);
this.appendChild(this.container_);
......
// Copyright (c) 2011 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.
/**
* @fileoverview Helper functions for use in tracing tests.
*/
cr.define('test_utils', function() {
function getJSON(url, cb) {
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onreadystatechange = function(aEvt) {
if (req.readyState == 4) {
window.setTimeout(function() {
if (req.status == 200) {
var resp = JSON.parse(req.responseText);
if (resp.traceEvents)
cb(resp.traceEvents);
else
cb(resp);
} else {
console.log('Failed to load ' + url);
}
}, 0);
}
};
req.send(null);
}
return {
getJSON: getJSON
};
});
\ No newline at end of file
[
{"name": "a", "args": {},"pid": 52, "ts": 9524, "cat": "foo", "tid": 53,
"ph": "B"},
{"name": "a", "args": {},"pid": 52, "ts": 9560, "cat": "foo", "tid": 53,
"ph": "E"},
{"name": "b", "args": {},"pid": 52, "ts": 9629, "cat": "foo", "tid": 53,
"ph": "B"},
{"name": "b", "args": {},"pid": 52, "ts": 9631, "cat": "foo", "tid": 53,
"ph": "E"},
{"name": "counter", "args": {"value": 2}, "pid": 52, "ts": 9524,
"cat": "foo", "tid": 53, "ph": "C", "id": "123"},
{"name": "counter", "args": {"value": 10}, "pid": 52, "ts": 9626,
"cat": "foo", "tid": 53, "ph": "C", "id": "123"},
{"name": "counter", "args": {"value": 5}, "pid": 52, "ts": 9627,
"cat": "foo", "tid": 53, "ph": "C", "id": "123"},
{"name": "counter", "args": {"value": 8}, "pid": 52, "ts": 9628,
"cat": "foo", "tid": 53, "ph": "C", "id": "123"},
{"name": "counter", "args": {"value": 4}, "pid": 52, "ts": 9629,
"cat": "foo", "tid": 53, "ph": "C", "id": "123"},
{"name": "counter", "args": {"value": 10}, "pid": 52, "ts": 9631,
"cat": "foo", "tid": 53, "ph": "C", "id": "123"},
{"name": "counter", "args": {"value": 10}, "pid": 52, "ts": 9524,
"cat": "foo", "tid": 53, "ph": "C", "id": "b"},
{"name": "counter", "args": {"value": 0}, "pid": 52, "ts": 9631,
"cat": "foo", "tid": 53, "ph": "C", "id": "b"}
]
\ No newline at end of file
[
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 826, "ph": "B",
"name": "A", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 827, "ph": "B",
"name": "Asub", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 829, "ph": "B",
"name": "NonNest", "args": {"id": "1", "ui-nest": "0"}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 830, "ph": "B",
"name": "NonNest", "args": {"id": "2", "ui-nest": "0"}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 831, "ph": "E",
"name": "Asub", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 832, "ph": "E",
"name": "NonNest", "args": {"id": "1", "ui-nest": "0"}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 833, "ph": "E",
"name": "NonNest", "args": {"id": "2", "ui-nest": "0"}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 834, "ph": "E",
"name": "A", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22631, "ts": 827, "ph": "B",
"name": "A", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22631, "ts": 854, "ph": "E",
"name": "A", "args": {}}
]
\ No newline at end of file
[
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 826, "ph": "C",
"name": "counter", "args": {"value": 10}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 826, "ph": "B",
"name": "A long name that doesnt fit but is exceedingly informative",
"args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 827, "ph": "B",
"name": "Asub with a name that wont fit", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 828, "ph": "E",
"name": "Asub", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 829, "ph": "B",
"name": "Asub", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 832, "ph": "E",
"name": "Asub", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 832, "ph": "C",
"name": "counter", "args": {"value": 1}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 833, "ph": "E",
"name": "", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 835, "ph": "I",
"name": "I1", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 837, "ph": "I",
"name": "I2", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 839, "ph": "C",
"name": "counter", "args": {"value": 5}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 840, "ph": "B",
"name": "A not as long a name", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 848, "ph": "E",
"name": "A not as long a name", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 848, "ph": "C",
"name": "counter", "args": {"value": 1}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 854, "ph": "C",
"name": "counter", "args": {"value": 10}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 850, "ph": "B",
"name": "B", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22630, "ts": 854, "ph": "E",
"name": "B", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22631, "ts": 827, "ph": "B",
"name": "A", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22631, "ts": 835, "ph": "I",
"name": "Immediate Three", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22631, "ts": 845, "ph": "I",
"name": "I4", "args": {}},
{"cat": "PERF", "pid": 22630, "tid": 22631, "ts": 854, "ph": "E",
"name": "A", "args": {}},
{"cat": "__metadata", "pid": 22630, "tid": 22630, "ts": 0, "ph": "M",
"name": "thread_name", "args": {"name": "threadA"}},
{"cat": "__metadata", "pid": 22630, "tid": 22631, "ts": 0, "ph": "M",
"name": "thread_name", "args": {"name": "threadB"}},
{"cat": "__metadata", "pid": 22630, "tid": 22632, "ts": 0, "ph": "M",
"name": "thread_name", "args": {"name": "threadC"}}
]
\ No newline at end of file
[
{"cat": "X", "pid": 30, "tid": 30, "ts": 826, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 30, "ts": 827, "ph": "B", "name": "Asub",
"args": {}},
{"cat": "X", "pid": 30, "tid": 30, "ts": 828, "ph": "E", "name": "Asub",
"args": {}},
{"cat": "X", "pid": 30, "tid": 30, "ts": 829, "ph": "B", "name": "Asub",
"args": {}},
{"cat": "X", "pid": 30, "tid": 30, "ts": 832, "ph": "E", "name": "Asub",
"args": {}},
{"cat": "X", "pid": 30, "tid": 30, "ts": 833, "ph": "E", "name": "",
"args": {}},
{"cat": "X", "pid": 30, "tid": 31, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 31, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 32, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 32, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 33, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 33, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 34, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 34, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 35, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 35, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 36, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 36, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 37, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 37, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 38, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 38, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 39, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 39, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 10, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 10, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 31, "tid": 11, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 31, "tid": 11, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 12, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 12, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 13, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 13, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 14, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 14, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 15, "ts": 840, "ph": "B", "name": "A",
"args": {}},
{"cat": "X", "pid": 30, "tid": 15, "ts": 848, "ph": "E", "name": "A",
"args": {}},
{"cat": "__metadata", "pid": 30, "tid": 14, "ts": 0, "ph": "M",
"name": "thread_name", "args": {"name": "thread12345678B"}},
{"cat": "__metadata", "pid": 30, "tid": 15, "ts": 0, "ph": "M",
"name": "thread_name", "args": {"name": "threadA"}}
]
\ No newline at end of file
[
{"name": "a", "args": {},"pid": 52, "ts": 9524, "cat": "foo", "tid": 53,
"ph": "B"},
{"name": "a", "args": {},"pid": 52, "ts": 9560, "cat": "foo", "tid": 53,
"ph": "E"},
{"name": "b", "args": {},"pid": 52, "ts": 9629, "cat": "foo", "tid": 53,
"ph": "B"},
{"name": "b", "args": {},"pid": 52, "ts": 9631, "cat": "foo", "tid": 53,
"ph": "E"}
]
\ No newline at end of file
......@@ -21,18 +21,17 @@ found in the LICENSE file.
border-top: 1px solid #D0D0D0;
}
.timeline-slice-track {
.timeline-canvas-based-track {
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
background-color: white;
display: -webkit-box;
height: 18px;
margin: 0;
padding: 0;
padding-right: 5px;
}
.timeline-slice-track-title {
.timeline-canvas-based-track-title {
overflow: hidden;
padding-right: 5px;
text-align: right;
......@@ -40,13 +39,21 @@ found in the LICENSE file.
white-space: nowrap;
}
.timeline-slice-track-canvas-container {
.timeline-canvas-based-track-canvas-container {
-webkit-box-flex: 1;
width: 100%;
}
.timeline-slice-track-canvas {
.timeline-canvas-based-track-canvas {
-webkit-box-flex: 1;
height: 100%;
width: 100%;
}
.timeline-slice-track {
height: 18px;
}
.timeline-counter-track {
height: 30px;
}
......@@ -30,13 +30,15 @@ cr.define('tracing', function() {
* All time units are stored in milliseconds.
* @constructor
*/
function TimelineSlice(title, colorId, start, args) {
function TimelineSlice(title, colorId, start, args, opt_duration) {
this.title = title;
this.start = start;
this.colorId = colorId;
this.args = args;
this.didNotFinish = false;
this.subSlices = [];
if (opt_duration !== undefined)
this.duration = opt_duration;
}
TimelineSlice.prototype = {
......@@ -112,6 +114,23 @@ cr.define('tracing', function() {
this.minTimestamp = undefined;
this.maxTimestamp = undefined;
}
},
/**
* @return {String} A user-friendly name for this thread.
*/
get userFriendlyName() {
var tname = this.name || this.tid;
return this.parent.pid + ': ' + tname;
},
/**
* @return {String} User friendly details about this thread.
*/
get userFriendlyDetials() {
return 'pid: ' + this.parent.pid +
', tid: ' + this.tid +
(this.name ? ', name: ' + this.name : '');
}
};
......@@ -122,7 +141,7 @@ cr.define('tracing', function() {
*/
TimelineThread.compare = function(x, y) {
if (x.parent.pid != y.parent.pid) {
return x.parent.pid - y.parent.pid;
return TimelineProcess.compare(x.parent, y.parent.pid);
}
if (x.name && y.name) {
......@@ -139,6 +158,78 @@ cr.define('tracing', function() {
}
};
/**
* Stores all the samples for a given counter.
* @constructor
*/
function TimelineCounter(parent, id, name) {
this.parent = parent;
this.id = id;
this.name = name;
this.seriesNames = [];
this.seriesColors = [];
this.timestamps = [];
this.samples = [];
}
TimelineCounter.prototype = {
__proto__: Object.prototype,
get numSeries() {
return this.seriesNames.length;
},
get numSamples() {
return this.timestamps.length;
},
/**
* Updates the bounds for this counter based on the samples it contains.
*/
updateBounds: function() {
if (this.seriesNames.length != this.seriesColors.length)
throw 'seriesNames.length must match seriesColors.length';
if (this.numSeries * this.numSamples != this.samples.length)
throw 'samples.length must be a multiple of numSamples.';
this.totals = [];
if (this.samples.length == 0) {
this.minTimestamp = undefined;
this.maxTimestamp = undefined;
this.maxTotal = 0;
return;
}
this.minTimestamp = this.timestamps[0];
this.maxTimestamp = this.timestamps[this.timestamps.length - 1];
var numSeries = this.numSeries;
var maxTotal = -Infinity;
for (var i = 0; i < this.timestamps.length; i++) {
var total = 0;
for (var j = 0; j < numSeries; j++) {
total += this.samples[i * numSeries + j];
this.totals.push(total);
}
if (total > maxTotal)
maxTotal = total;
}
this.maxTotal = maxTotal;
}
};
/**
* Comparison between counters that orders by pid, then name.
*/
TimelineCounter.compare = function(x, y) {
if (x.parent.pid != y.parent.pid) {
return TimelineProcess.compare(x.parent, y.parent.pid);
}
var tmp = x.name.localeCompare(y.name);
if (tmp == 0)
return x.tid - y.tid;
return tmp;
};
/**
* The TimelineProcess represents a single process in the
......@@ -149,6 +240,7 @@ cr.define('tracing', function() {
function TimelineProcess(pid) {
this.pid = pid;
this.threads = {};
this.counters = {};
};
TimelineProcess.prototype = {
......@@ -160,13 +252,35 @@ cr.define('tracing', function() {
return n;
},
/**
* @return {TimlineThread} The thread identified by tid on this process,
* creating it if it doesn't exist.
*/
getOrCreateThread: function(tid) {
if (!this.threads[tid])
this.threads[tid] = new TimelineThread(this, tid);
return this.threads[tid];
},
/**
* @return {TimlineCounter} The counter on this process named 'name',
* creating it if it doesn't exist.
*/
getOrCreateCounter: function(cat, name) {
var id = cat + '.' + name;
if (!this.counters[id])
this.counters[id] = new TimelineCounter(this, id, name);
return this.counters[id];
}
};
/**
* Comparison between processes that orders by pid.
*/
TimelineProcess.compare = function(x, y) {
return x.pid - y.pid;
};
/**
* Computes a simplistic hashcode of the provide name. Used to chose colors
* for slices.
......@@ -179,6 +293,20 @@ cr.define('tracing', function() {
return hash;
}
/**
* The number of color IDs that getStringColorId can choose from.
*/
const numColorIds = 30;
/**
* @return {Number} A color ID that is stably associated to the provided via
* the getStringHash method.
*/
function getStringColorId(string) {
var hash = getStringHash(string);
return hash % numColorIds;
}
/**
* Builds a model from an array of TraceEvent objects.
* @param {Array} events An array of TraceEvents created by
......@@ -218,8 +346,7 @@ cr.define('tracing', function() {
// The ptid is a unique key for a thread in the trace.
this.importErrors = [];
// Threadstate
const numColorIds = 30;
// Threadstate.
function ThreadState(tid) {
this.openSlices = [];
this.openNonNestedSlices = {};
......@@ -229,8 +356,7 @@ cr.define('tracing', function() {
var nameToColorMap = {};
function getColor(name) {
if (!(name in nameToColorMap)) {
var hash = getStringHash(name);
nameToColorMap[name] = hash % numColorIds;
nameToColorMap[name] = getStringColorId(name);
}
return nameToColorMap[name];
}
......@@ -328,6 +454,42 @@ cr.define('tracing', function() {
// TimelineSliceTrack's redraw() knows how to handle this.
processBegin(state, event);
processEnd(state, event);
} else if (event.ph == 'C') {
var ctr_name;
if (event.id !== undefined)
ctr_name = event.name + '[' + event.id + ']';
else
ctr_name = event.name;
var ctr = this.getOrCreateProcess(event.pid)
.getOrCreateCounter(event.cat, ctr_name);
// Initialize the counter's series fields if needed.
if (ctr.numSeries == 0) {
for (var seriesName in event.args) {
ctr.seriesNames.push(seriesName);
ctr.seriesColors.push(
getStringColorId(ctr.name + '.' + seriesName));
}
if (ctr.numSeries == 0) {
this.importErrors.push('Expected counter ' + event.name +
' to have at least one argument to use as a value.');
// Drop the counter.
delete ctr.parent.counters[ctr.name];
continue;
}
}
// Add the sample values.
ctr.timestamps.push(event.ts);
for (var i = 0; i < ctr.numSeries; i++) {
var seriesName = ctr.seriesNames[i];
if (event.args[seriesName] === undefined) {
ctr.samples.push(0);
continue;
}
ctr.samples.push(event.args[seriesName]);
}
} else if (event.ph == 'M') {
if (event.name == 'thread_name') {
var thread = this.getOrCreateProcess(event.pid)
......@@ -405,6 +567,16 @@ cr.define('tracing', function() {
wmax = Math.max(wmax, thread.maxTimestamp);
}
}
var counters = this.getAllCounters();
for (var tI = 0; tI < counters.length; tI++) {
var counter = counters[tI];
counter.updateBounds();
if (counter.minTimestamp != undefined &&
counter.maxTimestamp != undefined) {
wmin = Math.min(wmin, counter.minTimestamp);
wmax = Math.max(wmax, counter.maxTimestamp);
}
}
this.minTimestamp = wmin;
this.maxTimestamp = wmax;
},
......@@ -432,7 +604,12 @@ cr.define('tracing', function() {
shiftSubRow(thread.nonNestedSubRows[tSR]);
}
}
var counters = this.getAllCounters();
for (var tI = 0; tI < counters.length; tI++) {
var counter = counters[tI];
for (var sI = 0; sI < counter.timestamps.length; sI++)
counter.timestamps[sI] = (counter.timestamps[sI] - timeBase) / 1000;
}
this.updateBounds();
},
......@@ -445,14 +622,30 @@ cr.define('tracing', function() {
}
}
return threads;
},
/**
* @return {Array} An array of all the counters in the model.
*/
getAllCounters: function() {
var counters = [];
for (var pid in this.processes) {
var process = this.processes[pid];
for (var tid in process.counters) {
counters.push(process.counters[tid]);
}
}
return counters;
}
};
return {
getStringHash: getStringHash,
getStringColorId: getStringColorId,
TimelineSlice: TimelineSlice,
TimelineThread: TimelineThread,
TimelineCounter: TimelineCounter,
TimelineProcess: TimelineProcess,
TimelineModel: TimelineModel
};
......
<!DOCTYPE HTML>
<html>
<!--
Copyright (c) 2011 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.
-->
<head i18n-values="dir:textdirection;">
<title>Interactive Timeline Tests</title>
<link rel="stylesheet" href="timeline.css">
<script src="../shared/js/cr.js"></script>
<script src="../shared/js/cr/event_target.js"></script>
<script src="../shared/js/cr/ui.js"></script>
<script src="../shared/js/util.js"></script>
<script src="timeline_model.js"></script>
<script src="sorted_array_utils.js"></script>
<script src="measuring_stick.js"></script>
<script src="timeline.js"></script>
<script src="timeline_track.js"></script>
<script src="fast_rect_renderer.js"></script>
<script src="test_utils.js"></script>
</head>
<body>
<div class="timeline-test" src="./tests/trivial_trace.json" create-detached=1>
</div>
<div class="timeline-test" src="./tests/trivial_trace.json">
</div>
<div class="timeline-test" src="./tests/simple_trace.json">
</div>
<div class="timeline-test" src="./tests/instance_counters.json">
</div>
<div class="timeline-test" src="./tests/nonnested_trace.json">
</div>
<div class="timeline-test" src="./tests/tall_trace.json">
</div>
<div class="timeline-test" src="./tests/big_trace.json">
</div>
<div class="timeline-test" src="./tests/huge_trace.json">
</div>
<script>
function load(parentEl) {
var src = parentEl.getAttribute('src');
if (document.location.hash && document.location.hash.substring(1) != src) {
parentEl.hidden = true;
return;
}
parentEl.hidden = false;
parentEl.textContent = '';
var titleEl = document.createElement('h3');
var linkEl = document.createElement('a');
linkEl.textContent = src;
linkEl.href = '#' + src;
titleEl.appendChild(linkEl);
var containerEl = document.createElement('div');
containerEl.tabIndex = 0;
containerEl.style.border = '1px solid red';
var timelineEl = document.createElement('div');
cr.ui.decorate(timelineEl, tracing.Timeline);
timelineEl.focusElement = containerEl;
parentEl.appendChild(titleEl);
parentEl.appendChild(containerEl);
// Creating attached vs detached stress tests the canvas- and viewport-
// setup code.
var create_detached = parentEl.getAttribute('create-attached') == 1;
if (create_detached) {
containerEl.appendChild(timelineEl);
test_utils.getJSON(src, function(events) {
var model = new tracing.TimelineModel(events);
timelineEl.model = model;
});
} else {
test_utils.getJSON(src, function(events) {
var model = new tracing.TimelineModel(events);
timelineEl.model = model;
containerEl.appendChild(timelineEl);
});
}
}
function onLoad() {
Array.prototype.forEach.call(document.querySelectorAll('.timeline-test'),
load);
}
document.addEventListener('DOMContentLoaded', onLoad);
window.addEventListener('hashchange', onLoad);
</script>
</body>
</html>
<!DOCTYPE HTML>
<html>
<!--
Copyright (c) 2010 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.
-->
<head i18n-values="dir:textdirection;">
<title>TimelineTrack tests</title>
<script
src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js">
</script>
<script>
goog.require('goog.testing.jsunit');
</script>
<style>
* {
box-sizing: border-box;
-webkit-user-select: none;
}
.timeline-container {
border: 1px solid red;
}
</style>
<link rel="stylesheet" href="timeline.css">
<script src="../shared/js/cr.js"></script>
<script src="../shared/js/cr/event_target.js"></script>
<script src="../shared/js/cr/ui.js"></script>
<script src="../shared/js/util.js"></script>
<script src="timeline_model.js"></script>
<script src="sorted_array_utils.js"></script>
<script src="measuring_stick.js"></script>
<script src="timeline.js"></script>
<script src="timeline_track.js"></script>
<script src="fast_rect_renderer.js"></script>
</head>
<body>
<script>
</script>
<script>
var TimelineCounter = tracing.TimelineCounter;
var TimelineCounterTrack = tracing.TimelineCounterTrack;
var TimelineSliceTrack = tracing.TimelineSliceTrack;
var TimelineSlice = tracing.TimelineSlice;
var TimelineViewport = tracing.TimelineViewport;
var testDivs = {};
function getTestDiv(name) {
if (!testDivs[name]) {
testDivs[name] = document.createElement('div');
document.body.appendChild(testDivs[name]);
}
testDivs[name].textContent = '';
return testDivs[name];
}
function testBasicSlices() {
var testEl = getTestDiv('testBasicSlices');
var track = TimelineSliceTrack();
testEl.appendChild(track);
track.heading = 'testBasicSlices';
track.slices = [
new TimelineSlice('a', 0, 1, {}, 1),
new TimelineSlice('b', 1, 2.1, {}, 4.8),
new TimelineSlice('b', 1, 7, {}, 0.5),
new TimelineSlice('c', 2, 7.6, {}, 0.4)
];
track.viewport = new TimelineViewport(testEl);
track.viewport.setPanAndScale(0,
track.clientWidth / (1.1 * track.slices[track.slices.length - 1].end));
}
function testShrinkingSliceSizes() {
var testEl = getTestDiv('testShrinkingSliceSizes');
var track = TimelineSliceTrack();
testEl.appendChild(track);
track.heading = 'testShrinkingSliceSizes';
var x = 0;
var widths = [10, 5, 4, 3, 2, 1, 0.5, 0.4, 0.3, 0.2, 0.1, 0.05];
var slices = [];
for (var i = 0; i < widths.length; i++) {
var s = new TimelineSlice('a', 1, x, {}, widths[i]);
x += s.duration + 0.5;
slices.push(s);
}
track.slices = slices;
track.viewport = new TimelineViewport(testEl);
track.viewport.setPanAndScale(0,
track.clientWidth / (1.1 * track.slices[track.slices.length - 1].end));
}
function testPick() {
var testEl = getTestDiv('testPick');
var track = TimelineSliceTrack();
testEl.appendChild(track);
track.heading = 'testPick';
track.headingWidth = '100px';
track.slices = [
new TimelineSlice('a', 0, 1, {}, 1),
new TimelineSlice('b', 1, 2.1, {}, 4.8)
];
track.style.width = '500px';
track.viewport = new TimelineViewport(testEl);
track.viewport.setPanAndScale(0,
track.clientWidth / (1.1 * track.slices[track.slices.length - 1].end));
var clientRect = track.getBoundingClientRect();
var hits = [];
track.pick(1.5, clientRect.top + 5, function(x, y, z) { hits.push(z); });
assertEquals(track.slices[0], hits[0]);
hits = [];
track.pick(2, clientRect.top + 5, function(x, y, z) { hits.push(z); });
assertEquals(0, hits.length);
hits = [];
track.pick(6.8, clientRect.top + 5, function(x, y, z) { hits.push(z); });
assertEquals(track.slices[1], hits[0]);
hits = [];
track.pick(6.9, clientRect.top + 5, function(x, y, z) { hits.push(z); });
assertEquals(0, hits.length);
}
function testBasicCounter() {
var testEl = getTestDiv('testBasicCounter');
var ctr = new TimelineCounter(undefined, 'testBasicCounter', 'testBasicCounter');
ctr.numSeries = 1;
ctr.seriesNames = ['value1', 'value2'];
ctr.seriesColors = [tracing.getStringColorId('testBasicCounter.value1'),
tracing.getStringColorId('testBasicCounter.value2')];
ctr.timestamps = [0, 1, 2, 3, 4, 5, 6, 7];
ctr.samples = [0, 5,
3, 3,
1, 1,
2, 1.1,
3, 0,
1, 7,
3, 0,
3.1, 0.5];
ctr.updateBounds();
var track = TimelineCounterTrack();
testEl.appendChild(track);
track.heading = ctr.name;
track.counter = ctr;
track.viewport = new TimelineViewport(testEl);
track.viewport.setPanAndScale(0,
track.clientWidth / (1.1 * ctr.maxTimestamp));
}
</script>
</body>
</html>
......@@ -75,6 +75,7 @@ cr.define('tracing', function() {
this.timeline_.detach();
this.timeline_ = new tracing.Timeline();
this.timeline_.model = this.timelineModel_;
this.timeline_.focusElement = this.parentElement;
this.timelineContainer_.appendChild(this.timeline_);
this.timeline_.addEventListener('selectionChange',
this.onSelectionChangedBoundToThis_);
......
......@@ -27,13 +27,6 @@ cr.define('tracing', function() {
this.traceEvents_ = [];
if (browserBridge.debugMode) {
var tracingControllerTests = document.createElement('script');
tracingControllerTests.src =
'./tracing/tracing_controller_tests.js';
document.body.appendChild(tracingControllerTests);
}
this.onKeydownBoundToThis_ = this.onKeydown_.bind(this);
this.onKeypressBoundToThis_ = this.onKeypress_.bind(this);
......@@ -81,12 +74,8 @@ cr.define('tracing', function() {
this.statusDiv_.textContent = 'Tracing active.';
this.traceEvents_ = [];
if (!browserBridge.debugMode) {
chrome.send('beginTracing');
this.beginRequestBufferPercentFull_();
} else {
tracing.tracingControllerTestHarness.beginTracing();
}
chrome.send('beginTracing');
this.beginRequestBufferPercentFull_();
this.tracingEnabled_ = true;
......@@ -166,11 +155,7 @@ cr.define('tracing', function() {
// delay sending endTracingAsync until we get a chance to
// update the screen...
window.setTimeout(function() {
if (!browserBridge.debugMode) {
chrome.send('endTracingAsync');
} else {
tracing.tracingControllerTestHarness.endTracing();
}
chrome.send('endTracingAsync');
}, 100);
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment