blob: 7613b421254324c9d637d477c8bf92d45c2245ab [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="/tracing/base/time_display_modes.html">
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/extras/importer/trace_event_importer.html">
<link rel="import" href="/tracing/importer/import.html">
<link rel="import" href="/tracing/model/annotation.html">
<link rel="import" href="/tracing/model/model.html">
<script>
'use strict';
tr.b.unittest.testSuite(function() {
const ThreadSlice = tr.model.ThreadSlice;
const TitleOrCategoryFilter = tr.c.TitleOrCategoryFilter;
const Frame = tr.model.Frame;
const createModelWithOneOfEverything = function() {
const m = new tr.Model();
const cpu = m.kernel.getOrCreateCpu(1);
cpu.slices.push(tr.c.TestUtils.newSliceEx({start: 1, duration: 3}));
const p = m.getOrCreateProcess(1);
const t = p.getOrCreateThread(1);
const slice = new ThreadSlice('', 'a', 0, 1, {}, 4);
t.sliceGroup.pushSlice(slice);
t.asyncSliceGroup.push(tr.c.TestUtils.newAsyncSlice(0, 1, t, t));
const c = p.getOrCreateCounter('', 'ProcessCounter');
let aSeries = new tr.model.CounterSeries('a', 0);
let bSeries = new tr.model.CounterSeries('b', 0);
c.addSeries(aSeries);
c.addSeries(bSeries);
aSeries.addCounterSample(0, 5);
aSeries.addCounterSample(1, 6);
aSeries.addCounterSample(2, 5);
aSeries.addCounterSample(3, 7);
bSeries.addCounterSample(0, 10);
bSeries.addCounterSample(1, 15);
bSeries.addCounterSample(2, 12);
bSeries.addCounterSample(3, 16);
const c1 = cpu.getOrCreateCounter('', 'CpuCounter');
aSeries = new tr.model.CounterSeries('a', 0);
bSeries = new tr.model.CounterSeries('b', 0);
c1.addSeries(aSeries);
c1.addSeries(bSeries);
aSeries.addCounterSample(0, 5);
aSeries.addCounterSample(1, 6);
aSeries.addCounterSample(2, 5);
aSeries.addCounterSample(3, 7);
bSeries.addCounterSample(0, 10);
bSeries.addCounterSample(1, 15);
bSeries.addCounterSample(2, 12);
bSeries.addCounterSample(3, 16);
const frame1 = new Frame([slice], [{thread: t, start: 1, end: 5}]);
p.frames.push.apply(p.frames, frame1);
const gd = new tr.model.GlobalMemoryDump(m, 2);
const pd = new tr.model.ProcessMemoryDump(gd, p, 2);
gd.processMemoryDumps[1] = pd;
m.globalMemoryDumps.push(gd);
p.memoryDumps.push(pd);
m.updateBounds();
return m;
};
test('helper', function() {
function Helper(model) {
this.model = model;
}
Helper.guid = tr.b.GUID.allocateSimple();
Helper.supportsModel = function(model) {
return true;
};
const m = new tr.Model();
const h = m.getOrCreateHelper(Helper);
assert.isTrue(h instanceof Helper);
assert.isTrue(h === m.getOrCreateHelper(Helper));
function UnsupportedHelper(model) {
this.model = model;
}
UnsupportedHelper.guid = tr.b.GUID.allocateSimple();
UnsupportedHelper.supportsModel = function(model) {
return false;
};
assert.isUndefined(m.getOrCreateHelper(UnsupportedHelper));
// Try again to test doesHelperGUIDSupportThisModel_ .
assert.isUndefined(m.getOrCreateHelper(UnsupportedHelper));
});
test('modelBounds_EmptyModel', function() {
const m = new tr.Model();
m.updateBounds();
assert.isUndefined(m.bounds.min);
assert.isUndefined(m.bounds.max);
});
test('modelBounds_OneEmptyThread', function() {
const m = new tr.Model();
const t = m.getOrCreateProcess(1).getOrCreateThread(1);
m.updateBounds();
assert.isUndefined(m.bounds.min);
assert.isUndefined(m.bounds.max);
});
test('modelBounds_OneThread', function() {
const m = new tr.Model();
const t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 3));
m.updateBounds();
assert.strictEqual(m.bounds.min, 1);
assert.strictEqual(m.bounds.max, 4);
});
test('modelBounds_OneThreadAndOneEmptyThread', function() {
const m = new tr.Model();
const t1 = m.getOrCreateProcess(1).getOrCreateThread(1);
t1.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 3));
const t2 = m.getOrCreateProcess(1).getOrCreateThread(1);
m.updateBounds();
assert.strictEqual(m.bounds.min, 1);
assert.strictEqual(m.bounds.max, 4);
});
test('modelBounds_OneCpu', function() {
const m = new tr.Model();
const cpu = m.kernel.getOrCreateCpu(1);
cpu.slices.push(tr.c.TestUtils.newSliceEx({start: 1, duration: 3}));
m.updateBounds();
assert.strictEqual(m.bounds.min, 1);
assert.strictEqual(m.bounds.max, 4);
});
test('modelBounds_OneCpuOneThread', function() {
const m = new tr.Model();
const cpu = m.kernel.getOrCreateCpu(1);
cpu.slices.push(tr.c.TestUtils.newSliceEx({start: 1, duration: 3}));
const t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 4));
m.updateBounds();
assert.strictEqual(m.bounds.min, 1);
assert.strictEqual(m.bounds.max, 5);
});
test('modelBounds_GlobalMemoryDumps', function() {
const m = new tr.Model();
m.globalMemoryDumps.push(new tr.model.GlobalMemoryDump(m, 1));
m.globalMemoryDumps.push(new tr.model.GlobalMemoryDump(m, 3));
m.globalMemoryDumps.push(new tr.model.GlobalMemoryDump(m, 5));
m.updateBounds();
assert.strictEqual(m.bounds.min, 1);
assert.strictEqual(m.bounds.max, 5);
});
test('modelBounds_ProcessMemoryDumps', function() {
const m = new tr.Model();
const p = m.getOrCreateProcess(1);
const gd = new tr.model.GlobalMemoryDump(m, -1);
p.memoryDumps.push(new tr.model.ProcessMemoryDump(gd, m, 1));
p.memoryDumps.push(new tr.model.ProcessMemoryDump(gd, m, 3));
p.memoryDumps.push(new tr.model.ProcessMemoryDump(gd, m, 5));
m.updateBounds();
assert.strictEqual(m.bounds.min, 1);
assert.strictEqual(m.bounds.max, 5);
});
test('modelConvertsTimestampToModelTime', function() {
const m = new tr.Model();
const traceEvents = [
{ts: 1000, pid: 1, tid: 1, ph: 'B', cat: 'a', name: 'taskA', args: {}},
{ts: 2000, pid: 1, tid: 1, ph: 'E', cat: 'a', name: 'taskA', args: {}}
];
const i = new tr.importer.Import(m);
i.importTraces([traceEvents]);
assert.strictEqual(
m.convertTimestampToModelTime('traceEventClock', 1000), 0);
assert.strictEqual(
m.convertTimestampToModelTime('traceEventClock', 2000), 1);
});
test('TitleOrCategoryFilter', function() {
const s0 = tr.c.TestUtils.newSliceEx({start: 1, duration: 3});
assert.isTrue(new TitleOrCategoryFilter('a').matchSlice(s0));
assert.isFalse(new TitleOrCategoryFilter('x').matchSlice(s0));
const s1 = tr.c.TestUtils.newSliceEx({title: 'ba', start: 1, duration: 3});
assert.isTrue(new TitleOrCategoryFilter('a').matchSlice(s1));
assert.isTrue(new TitleOrCategoryFilter('ba').matchSlice(s1));
assert.isFalse(new TitleOrCategoryFilter('x').matchSlice(s1));
});
test('model_findAllThreadsNamed', function() {
const m = new tr.Model();
const t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.name = 'CrBrowserMain';
m.updateBounds();
let f = m.findAllThreadsNamed('CrBrowserMain');
assert.deepEqual([t], f);
f = m.findAllThreadsNamed('NoSuchThread');
assert.strictEqual(f.length, 0);
});
test('model_updateCategories', function() {
const m = new tr.Model();
const t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.sliceGroup.pushSlice(new ThreadSlice('categoryA', 'a', 0, 1, {}, 3));
t.sliceGroup.pushSlice(new ThreadSlice('categoryA', 'a', 0, 1, {}, 3));
t.sliceGroup.pushSlice(new ThreadSlice('categoryB', 'a', 0, 1, {}, 3));
t.sliceGroup.pushSlice(new ThreadSlice('categoryA', 'a', 0, 1, {}, 3));
t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 3));
m.updateCategories_();
assert.deepEqual(['categoryA', 'categoryB'], m.categories);
});
test('getEventByStableId', function() {
const m = new tr.Model();
const p = m.getOrCreateProcess(0);
const t = p.getOrCreateThread(1);
const slice = tr.c.TestUtils.newSliceEx({start: 0, duration: 10});
t.sliceGroup.pushSlice(slice);
const ue = tr.c.TestUtils.newInteractionRecord(m, 0, 10);
m.userModel.expectations.push(ue);
const gie = tr.c.TestUtils.newInstantEvent({
title: 'gie',
start: 0,
colorId: 0
});
m.instantEvents.push(gie);
assert.strictEqual(slice, m.getEventByStableId(slice.stableId));
assert.strictEqual(ue, m.getEventByStableId(ue.stableId));
assert.strictEqual(gie, m.getEventByStableId(gie.stableId));
});
test('model_annotationAddRemove', function() {
const m = new tr.Model();
const a1 = new tr.model.Annotation();
const a2 = new tr.model.Annotation();
assert.strictEqual(m.getAllAnnotations().length, 0);
m.addAnnotation(a1);
assert.strictEqual(m.getAllAnnotations().length, 1);
m.addAnnotation(a2);
assert.strictEqual(m.getAllAnnotations().length, 2);
assert.strictEqual(m.getAnnotationByGUID(a1.guid), a1);
assert.strictEqual(m.getAnnotationByGUID(a2.guid), a2);
m.removeAnnotation(a1);
assert.isUndefined(m.getAnnotationByGUID(a1.guid));
assert.strictEqual(m.getAnnotationByGUID(a2.guid), a2);
assert.strictEqual(m.getAllAnnotations().length, 1);
});
test('model_intrinsicTimeUnit', function() {
const unit = tr.b.TimeDisplayModes;
const m = new tr.Model();
// by default it should be milliseconds
assert.strictEqual(m.intrinsicTimeUnit, unit.ms);
m.intrinsicTimeUnit = unit.ns;
assert.strictEqual(m.intrinsicTimeUnit, unit.ns);
// should be able to set to the same
m.intrinsicTimeUnit = unit.ns;
assert.strictEqual(m.intrinsicTimeUnit, unit.ns);
// should not be able to change it after fixing it
assert.throw(function() { m.intrinsicTimeUnit = unit.ms; });
assert.strictEqual(m.intrinsicTimeUnit, unit.ns);
});
test('model_getAllProcesses', function() {
const m = new tr.Model();
const p1 = m.getOrCreateProcess(1);
const p2 = m.getOrCreateProcess(2);
const p3 = m.getOrCreateProcess(3);
const p4 = m.getOrCreateProcess(4);
const p5 = m.getOrCreateProcess(5);
assert.sameMembers(m.getAllProcesses(), [p1, p2, p3, p4, p5]);
assert.sameMembers(m.getAllProcesses(p => true), [p1, p2, p3, p4, p5]);
assert.sameMembers(m.getAllProcesses(p => false), []);
assert.sameMembers(m.getAllProcesses(p => p.pid % 2 === 0), [p2, p4]);
});
test('model_joinRefs', function() {
function RefCountingSnapshot() {
tr.model.ObjectSnapshot.apply(this, arguments);
this.refCount = 0;
}
RefCountingSnapshot.prototype = {
__proto__: tr.model.ObjectSnapshot.prototype,
referencedAt() {
++this.refCount;
}
};
const typeName = 'RefCountingSnapshot';
tr.model.ObjectSnapshot.subTypes.register(
RefCountingSnapshot,
{typeName});
const m = new tr.Model();
const p = m.getOrCreateProcess(1);
const s1 = p.objects.addSnapshot(new tr.model.ScopedId(typeName, '0x1'),
'cat', typeName, 1000, {});
const s2 = p.objects.addSnapshot(new tr.model.ScopedId(typeName, '0x2'),
'cat', typeName, 2000, {
myRef: {
scope: typeName,
id_ref: '0x1'
}
});
m.joinRefs();
assert.strictEqual(s1.refCount, 1);
assert.strictEqual(s2.refCount, 0);
});
});
</script>