// 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.
'use strict';
base.require('tracing.test_utils');
base.require('tracing.trace_model');
base.require('tracing.importer');
base.unittest.testSuite('tracing.trace_model', function() {
var ThreadSlice = tracing.trace_model.ThreadSlice;
var TraceModel = tracing.TraceModel;
var TitleFilter = tracing.TitleFilter;
var createTraceModelWithOneOfEverything = function() {
var m = new TraceModel();
var cpu = m.kernel.getOrCreateCpu(1);
cpu.slices.push(tracing.test_utils.newSlice(1, 3));
var p = m.getOrCreateProcess(1);
var t = p.getOrCreateThread(1);
t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 4));
t.asyncSliceGroup.push(tracing.test_utils.newAsyncSlice(0, 1, t, t));
var c = p.getOrCreateCounter('', 'ProcessCounter');
var aSeries = new tracing.trace_model.CounterSeries('a', 0);
var bSeries = new tracing.trace_model.CounterSeries('b', 0);
c.addSeries(aSeries);
c.addSeries(bSeries);
aSeries.addSample(0, 5);
aSeries.addSample(1, 6);
aSeries.addSample(2, 5);
aSeries.addSample(3, 7);
bSeries.addSample(0, 10);
bSeries.addSample(1, 15);
bSeries.addSample(2, 12);
bSeries.addSample(3, 16);
var c1 = cpu.getOrCreateCounter('', 'CpuCounter');
var aSeries = new tracing.trace_model.CounterSeries('a', 0);
var bSeries = new tracing.trace_model.CounterSeries('b', 0);
c1.addSeries(aSeries);
c1.addSeries(bSeries);
aSeries.addSample(0, 5);
aSeries.addSample(1, 6);
aSeries.addSample(2, 5);
aSeries.addSample(3, 7);
bSeries.addSample(0, 10);
bSeries.addSample(1, 15);
bSeries.addSample(2, 12);
bSeries.addSample(3, 16);
m.updateBounds();
return m;
};
test('traceModelBounds_EmptyTraceModel', function() {
var m = new TraceModel();
m.updateBounds();
assertEquals(undefined, m.bounds.min);
assertEquals(undefined, m.bounds.max);
});
test('traceModelBounds_OneEmptyThread', function() {
var m = new TraceModel();
var t = m.getOrCreateProcess(1).getOrCreateThread(1);
m.updateBounds();
assertEquals(undefined, m.bounds.min);
assertEquals(undefined, m.bounds.max);
});
test('traceModelBounds_OneThread', function() {
var m = new TraceModel();
var t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 3));
m.updateBounds();
assertEquals(1, m.bounds.min);
assertEquals(4, m.bounds.max);
});
test('traceModelBounds_OneThreadAndOneEmptyThread', function() {
var m = new TraceModel();
var t1 = m.getOrCreateProcess(1).getOrCreateThread(1);
t1.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 3));
var t2 = m.getOrCreateProcess(1).getOrCreateThread(1);
m.updateBounds();
assertEquals(1, m.bounds.min);
assertEquals(4, m.bounds.max);
});
test('traceModelBounds_OneCpu', function() {
var m = new TraceModel();
var cpu = m.kernel.getOrCreateCpu(1);
cpu.slices.push(tracing.test_utils.newSlice(1, 3));
m.updateBounds();
assertEquals(1, m.bounds.min);
assertEquals(4, m.bounds.max);
});
test('traceModelBounds_OneCpuOneThread', function() {
var m = new TraceModel();
var cpu = m.kernel.getOrCreateCpu(1);
cpu.slices.push(tracing.test_utils.newSlice(1, 3));
var t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 4));
m.updateBounds();
assertEquals(1, m.bounds.min);
assertEquals(5, m.bounds.max);
});
test('traceModelCanImportEmpty', function() {
var m;
m = new TraceModel([]);
m = new TraceModel('');
});
test('traceModelCanImportSubtraces', function() {
var systraceLines = [
'SurfaceFlinger-2 [001] ...1 1000.0: 0: B|1|taskA',
'SurfaceFlinger-2 [001] ...1 2000.0: 0: E'
];
var traceEvents = [
{ts: 1000, pid: 1, tid: 3, ph: 'B', cat: 'c', name: 'taskB', args: {
my_object: {id_ref: '0x1000'}
}},
{ts: 2000, pid: 1, tid: 3, ph: 'E', cat: 'c', name: 'taskB', args: {}}
];
var combined = JSON.stringify({
traceEvents: traceEvents,
systemTraceEvents: systraceLines.join('\n')
});
var m = new TraceModel();
m.importTraces([combined]);
assertEquals(1, base.dictionaryValues(m.processes).length);
var p1 = m.processes[1];
assertNotUndefined(p1);
var t2 = p1.threads[2];
var t3 = p1.threads[3];
assertNotUndefined(t2);
assertNotUndefined(t3);
assertEquals(1, t2.sliceGroup.length, 1);
assertEquals('taskA', t2.sliceGroup.slices[0].title);
assertEquals(1, t3.sliceGroup.length);
assertEquals('taskB', t3.sliceGroup.slices[0].title);
});
test('traceModelWithImportFailure', function() {
var malformed = '{traceEvents: [{garbage';
var m = new TraceModel();
assertThrows(function() {
m.importTraces([malformed]);
});
});
test('titleFilter', function() {
var s0 = tracing.test_utils.newSlice(1, 3);
assertFalse(new TitleFilter('').matchSlice(s0));
assertTrue(new TitleFilter('a').matchSlice(s0));
assertFalse(new TitleFilter('x').matchSlice(s0));
var s1 = tracing.test_utils.newSliceNamed('ba', 1, 3);
assertTrue(new TitleFilter('a').matchSlice(s1));
assertTrue(new TitleFilter('ba').matchSlice(s1));
assertFalse(new TitleFilter('x').matchSlice(s1));
});
test('traceModel_toJSON', function() {
var m = createTraceModelWithOneOfEverything();
assertNotNull(JSON.stringify(m));
});
test('traceModel_findAllThreadsNamed', function() {
var m = new TraceModel();
var t = m.getOrCreateProcess(1).getOrCreateThread(1);
t.name = 'CrBrowserMain';
m.updateBounds();
var f = m.findAllThreadsNamed('CrBrowserMain');
assertArrayEquals([t], f);
f = m.findAllThreadsNamed('NoSuchThread');
assertEquals(0, f.length);
});
test('traceModel_updateCategories', function() {
var m = new TraceModel();
var 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_();
assertArrayEquals(['categoryA', 'categoryB'], m.categories);
});
});