| <!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/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"> |
| <link rel="import" href="/tracing/value/time_display_mode.html"> |
| |
| <script> |
| 'use strict'; |
| |
| tr.b.unittest.testSuite(function() { |
| var ThreadSlice = tr.model.ThreadSlice; |
| var TitleOrCategoryFilter = tr.c.TitleOrCategoryFilter; |
| var Frame = tr.model.Frame; |
| |
| var createModelWithOneOfEverything = function() { |
| var m = new tr.Model(); |
| var cpu = m.kernel.getOrCreateCpu(1); |
| cpu.slices.push(tr.c.TestUtils.newSliceEx({start: 1, duration: 3})); |
| |
| var p = m.getOrCreateProcess(1); |
| var t = p.getOrCreateThread(1); |
| var slice = new ThreadSlice('', 'a', 0, 1, {}, 4); |
| t.sliceGroup.pushSlice(slice); |
| t.asyncSliceGroup.push(tr.c.TestUtils.newAsyncSlice(0, 1, t, t)); |
| |
| var c = p.getOrCreateCounter('', 'ProcessCounter'); |
| var aSeries = new tr.model.CounterSeries('a', 0); |
| var 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); |
| |
| var c1 = cpu.getOrCreateCounter('', 'CpuCounter'); |
| var aSeries = new tr.model.CounterSeries('a', 0); |
| var 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); |
| |
| var frame1 = new Frame([slice], [{thread: t, start: 1, end: 5}]); |
| p.frames.push.apply(p.frames, frame1); |
| |
| var gd = new tr.model.GlobalMemoryDump(m, 2); |
| var 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.allocate(); |
| Helper.supportsModel = function(model) { |
| return true; |
| }; |
| |
| var m = new tr.Model(); |
| var 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.allocate(); |
| 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() { |
| var m = new tr.Model(); |
| m.updateBounds(); |
| assert.isUndefined(m.bounds.min); |
| assert.isUndefined(m.bounds.max); |
| }); |
| |
| test('modelBounds_OneEmptyThread', function() { |
| var m = new tr.Model(); |
| var t = m.getOrCreateProcess(1).getOrCreateThread(1); |
| m.updateBounds(); |
| assert.isUndefined(m.bounds.min); |
| assert.isUndefined(m.bounds.max); |
| }); |
| |
| test('modelBounds_OneThread', function() { |
| var m = new tr.Model(); |
| var t = m.getOrCreateProcess(1).getOrCreateThread(1); |
| t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 3)); |
| m.updateBounds(); |
| assert.equal(m.bounds.min, 1); |
| assert.equal(m.bounds.max, 4); |
| }); |
| |
| test('modelBounds_OneThreadAndOneEmptyThread', function() { |
| var m = new tr.Model(); |
| 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(); |
| assert.equal(m.bounds.min, 1); |
| assert.equal(m.bounds.max, 4); |
| }); |
| |
| test('modelBounds_OneCpu', function() { |
| var m = new tr.Model(); |
| var cpu = m.kernel.getOrCreateCpu(1); |
| cpu.slices.push(tr.c.TestUtils.newSliceEx({start: 1, duration: 3})); |
| m.updateBounds(); |
| assert.equal(m.bounds.min, 1); |
| assert.equal(m.bounds.max, 4); |
| }); |
| |
| test('modelBounds_OneCpuOneThread', function() { |
| var m = new tr.Model(); |
| var cpu = m.kernel.getOrCreateCpu(1); |
| cpu.slices.push(tr.c.TestUtils.newSliceEx({start: 1, duration: 3})); |
| |
| var t = m.getOrCreateProcess(1).getOrCreateThread(1); |
| t.sliceGroup.pushSlice(new ThreadSlice('', 'a', 0, 1, {}, 4)); |
| |
| m.updateBounds(); |
| assert.equal(m.bounds.min, 1); |
| assert.equal(m.bounds.max, 5); |
| }); |
| |
| test('modelBounds_GlobalMemoryDumps', function() { |
| var 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.equal(m.bounds.min, 1); |
| assert.equal(m.bounds.max, 5); |
| }); |
| |
| test('modelBounds_ProcessMemoryDumps', function() { |
| var m = new tr.Model(); |
| var p = m.getOrCreateProcess(1); |
| var 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.equal(m.bounds.min, 1); |
| assert.equal(m.bounds.max, 5); |
| }); |
| |
| |
| test('modelConvertsTimestampToModelTime', function() { |
| var m = new tr.Model(); |
| var 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: {}} |
| ]; |
| var i = new tr.importer.Import(m); |
| i.importTraces([traceEvents]); |
| assert.equal(m.convertTimestampToModelTime('traceEventClock', 1000), 0); |
| assert.equal(m.convertTimestampToModelTime('traceEventClock', 2000), 1); |
| }); |
| |
| test('TitleOrCategoryFilter', function() { |
| var s0 = tr.c.TestUtils.newSliceEx({start: 1, duration: 3}); |
| assert.isTrue(new TitleOrCategoryFilter('a').matchSlice(s0)); |
| assert.isFalse(new TitleOrCategoryFilter('x').matchSlice(s0)); |
| |
| var 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() { |
| var m = new tr.Model(); |
| var t = m.getOrCreateProcess(1).getOrCreateThread(1); |
| t.name = 'CrBrowserMain'; |
| |
| m.updateBounds(); |
| var f = m.findAllThreadsNamed('CrBrowserMain'); |
| assert.deepEqual([t], f); |
| f = m.findAllThreadsNamed('NoSuchThread'); |
| assert.equal(f.length, 0); |
| }); |
| |
| test('model_updateCategories', function() { |
| var m = new tr.Model(); |
| 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_(); |
| assert.deepEqual(['categoryA', 'categoryB'], m.categories); |
| }); |
| |
| test('model_iterateAllEvents', function() { |
| var m = createModelWithOneOfEverything(); |
| var wasCalled = false; |
| m.iterateAllEvents(function(event) { |
| assert.isTrue(event instanceof tr.model.Event); |
| wasCalled = true; |
| }); |
| assert.isTrue(wasCalled); |
| }); |
| |
| test('model_annotationAddRemove', function() { |
| var m = new tr.Model(); |
| var a1 = new tr.model.Annotation(); |
| var a2 = new tr.model.Annotation(); |
| |
| assert.equal(m.getAllAnnotations().length, 0); |
| m.addAnnotation(a1); |
| assert.equal(m.getAllAnnotations().length, 1); |
| m.addAnnotation(a2); |
| assert.equal(m.getAllAnnotations().length, 2); |
| |
| assert.equal(m.getAnnotationByGUID(a1.guid), a1); |
| assert.equal(m.getAnnotationByGUID(a2.guid), a2); |
| |
| m.removeAnnotation(a1); |
| assert.isUndefined(m.getAnnotationByGUID(a1.guid)); |
| assert.equal(m.getAnnotationByGUID(a2.guid), a2); |
| assert.equal(m.getAllAnnotations().length, 1); |
| }); |
| |
| test('model_intrinsicTimeUnit', function() { |
| var unit = tr.v.TimeDisplayModes; |
| var m = new tr.Model(); |
| |
| // by default it should be milliseconds |
| assert.equal(m.intrinsicTimeUnit, unit.ms); |
| |
| m.intrinsicTimeUnit = unit.ns; |
| assert.equal(m.intrinsicTimeUnit, unit.ns); |
| // should be able to set to the same |
| m.intrinsicTimeUnit = unit.ns; |
| assert.equal(m.intrinsicTimeUnit, unit.ns); |
| // should not be able to change it after fixing it |
| assert.throw(function() { m.intrinsicTimeUnit = unit.ms; }); |
| assert.equal(m.intrinsicTimeUnit, unit.ns); |
| }); |
| |
| test('model_highResolutionHeuristicTrue', function() { |
| var m = new tr.Model(); |
| var t = m.getOrCreateProcess(1).getOrCreateThread(1); |
| // A thousand event not aligned on a millisecond. |
| for (var i = 0; i < 1000; ++i) { |
| var start = 0.53 * i; |
| t.sliceGroup.pushSlice(new ThreadSlice('c', 'a', 0, start, {}, 1)); |
| } |
| assert.isTrue(m.isTimeHighResolution); |
| }); |
| |
| test('model_highResolutionHeuristicFalse', function() { |
| var m = new tr.Model(); |
| var t = m.getOrCreateProcess(1).getOrCreateThread(1); |
| // A thousand event aligned on a millisecond. |
| for (var i = 0; i < 1000; ++i) { |
| var start = 0.753 + i; |
| t.sliceGroup.pushSlice(new ThreadSlice('c', 'a', 0, start, {}, 1)); |
| } |
| // And fifty not aligned on anything. |
| for (var i = 0; i < 50; ++i) { |
| var start = 0.53 * i; |
| t.sliceGroup.pushSlice(new ThreadSlice('c', 'a', 0, start, {}, 1)); |
| } |
| assert.isFalse(m.isTimeHighResolution); |
| }); |
| |
| }); |
| </script> |