<!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="/core/test_utils.html">
<link rel="import" href="/core/trace_model/annotation.html">
<link rel="import" href="/core/trace_model/trace_model.html">
<link rel="import" href="/extras/full_config.html">

<script>
'use strict';

tv.b.unittest.testSuite(function() {
  var ThreadSlice = tv.c.trace_model.ThreadSlice;
  var TraceModel = tv.c.TraceModel;
  var TitleOrCategoryFilter = tv.c.TitleOrCategoryFilter;
  var Frame = tv.c.trace_model.Frame;

  var createTraceModelWithOneOfEverything = function() {
    var m = new TraceModel();
    var cpu = m.kernel.getOrCreateCpu(1);
    cpu.slices.push(tv.c.test_utils.newSlice(1, 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(tv.c.test_utils.newAsyncSlice(0, 1, t, t));

    var c = p.getOrCreateCounter('', 'ProcessCounter');
    var aSeries = new tv.c.trace_model.CounterSeries('a', 0);
    var bSeries = new tv.c.trace_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 tv.c.trace_model.CounterSeries('a', 0);
    var bSeries = new tv.c.trace_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 tv.c.trace_model.GlobalMemoryDump(m, 2);
    var pd = new tv.c.trace_model.ProcessMemoryDump(gd, p, 2);
    gd.processMemoryDumps[1] = pd;
    m.globalMemoryDumps.push(gd);
    p.memoryDumps.push(pd);

    m.updateBounds();

    return m;
  };

  test('traceModelBounds_EmptyTraceModel', function() {
    var m = new TraceModel();
    m.updateBounds();
    assert.isUndefined(m.bounds.min);
    assert.isUndefined(m.bounds.max);
  });

  test('traceModelBounds_OneEmptyThread', function() {
    var m = new TraceModel();
    var t = m.getOrCreateProcess(1).getOrCreateThread(1);
    m.updateBounds();
    assert.isUndefined(m.bounds.min);
    assert.isUndefined(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();
    assert.equal(m.bounds.min, 1);
    assert.equal(m.bounds.max, 4);
  });

  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();
    assert.equal(m.bounds.min, 1);
    assert.equal(m.bounds.max, 4);
  });

  test('traceModelBounds_OneCpu', function() {
    var m = new TraceModel();
    var cpu = m.kernel.getOrCreateCpu(1);
    cpu.slices.push(tv.c.test_utils.newSlice(1, 3));
    m.updateBounds();
    assert.equal(m.bounds.min, 1);
    assert.equal(m.bounds.max, 4);
  });

  test('traceModelBounds_OneCpuOneThread', function() {
    var m = new TraceModel();
    var cpu = m.kernel.getOrCreateCpu(1);
    cpu.slices.push(tv.c.test_utils.newSlice(1, 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('traceModelBounds_GlobalMemoryDumps', function() {
    var m = new TraceModel();
    m.globalMemoryDumps.push(new tv.c.trace_model.GlobalMemoryDump(m, 1));
    m.globalMemoryDumps.push(new tv.c.trace_model.GlobalMemoryDump(m, 3));
    m.globalMemoryDumps.push(new tv.c.trace_model.GlobalMemoryDump(m, 5));

    m.updateBounds();
    assert.equal(m.bounds.min, 1);
    assert.equal(m.bounds.max, 5);
  });

  test('traceModelBounds_ProcessMemoryDumps', function() {
    var m = new TraceModel();
    var p = m.getOrCreateProcess(1);
    var gd = new tv.c.trace_model.GlobalMemoryDump(m, -1);
    p.memoryDumps.push(new tv.c.trace_model.ProcessMemoryDump(gd, m, 1));
    p.memoryDumps.push(new tv.c.trace_model.ProcessMemoryDump(gd, m, 3));
    p.memoryDumps.push(new tv.c.trace_model.ProcessMemoryDump(gd, m, 5));

    m.updateBounds();
    assert.equal(m.bounds.min, 1);
    assert.equal(m.bounds.max, 5);
  });

  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',
      '        chrome-3  [001] ...1 2000.0: 0: trace_event_clock_sync: ' +
          'parent_ts=0'
    ];
    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]);
    assert.equal(tv.b.dictionaryValues(m.processes).length, 1);

    var p1 = m.processes[1];
    assert.isDefined(p1);

    var t2 = p1.threads[2];
    var t3 = p1.threads[3];
    assert.isDefined(t2);
    assert.isDefined(t3);

    assert.equal(1, 1, t2.sliceGroup.length);
    assert.equal(t2.sliceGroup.slices[0].title, 'taskA');

    assert.equal(t3.sliceGroup.length, 1);
    assert.equal(t3.sliceGroup.slices[0].title, 'taskB');
  });

  test('traceModelCanImportCompressedSingleSubtrace', function() {
    var compressedTrace = atob('H4sIACKfFVUC/wsuLUpLTE51y8nMS08t0jVSUIg2MDCMV' +
        'dDT0zNUMDQwMNAzsFIAIqcaw5qSxOJsR65gfDqMEDpcATiC61ZbAAAA');
    var m = new TraceModel();
    m.importTraces([compressedTrace]);
    assert.equal(1, tv.b.dictionaryValues(m.processes).length);

    var p1 = m.processes[1];
    assert.isDefined(p1);

    var t2 = p1.threads[2];
    assert.isDefined(t2);

    assert.equal(1, t2.sliceGroup.length, 1);
    assert.equal('taskA', t2.sliceGroup.slices[0].title);
  });

  test('traceModelCanImportSubtracesRecursively', function() {
    var systraceLines = [
      'SurfaceFlinger-2  [001] ...1 1000.0: 0: B|1|taskA',
      'SurfaceFlinger-2  [001] ...1 2000.0: 0: E',
      '        chrome-3  [001] ...1 2000.0: 0: trace_event_clock_sync: ' +
          'parent_ts=0'
    ];
    var outerTraceEvents = [
      {ts: 1000, pid: 1, tid: 3, ph: 'B', cat: 'c', name: 'taskB', args: {
        my_object: {id_ref: '0x1000'}
      }}
    ];

    var innerTraceEvents = [
      {ts: 2000, pid: 1, tid: 3, ph: 'E', cat: 'c', name: 'taskB', args: {}}
    ];

    var innerTrace = JSON.stringify({
      traceEvents: innerTraceEvents,
      systemTraceEvents: systraceLines.join('\n')
    });

    var outerTrace = JSON.stringify({
      traceEvents: outerTraceEvents,
      systemTraceEvents: innerTrace
    });

    var m = new TraceModel();
    m.importTraces([outerTrace]);
    assert.equal(tv.b.dictionaryValues(m.processes).length, 1);

    var p1 = m.processes[1];
    assert.isDefined(p1);

    var t2 = p1.threads[2];
    var t3 = p1.threads[3];
    assert.isDefined(t2);
    assert.isDefined(t3);

    assert.equal(1, 1, t2.sliceGroup.length);
    assert.equal(t2.sliceGroup.slices[0].title, 'taskA');

    assert.equal(t3.sliceGroup.length, 1);
    assert.equal(t3.sliceGroup.slices[0].title, 'taskB');
  });

  test('traceModelWithImportFailure', function() {
    var malformed = '{traceEvents: [{garbage';
    var m = new TraceModel();
    assert.throw(function() {
      m.importTraces([malformed]);
    });
  });

  test('TitleOrCategoryFilter', function() {
    var s0 = tv.c.test_utils.newSlice(1, 3);
    assert.isTrue(new TitleOrCategoryFilter('a').matchSlice(s0));
    assert.isFalse(new TitleOrCategoryFilter('x').matchSlice(s0));

    var s1 = tv.c.test_utils.newSliceNamed('ba', 1, 3);
    assert.isTrue(new TitleOrCategoryFilter('a').matchSlice(s1));
    assert.isTrue(new TitleOrCategoryFilter('ba').matchSlice(s1));
    assert.isFalse(new TitleOrCategoryFilter('x').matchSlice(s1));
  });

  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');
    assert.deepEqual([t], f);
    f = m.findAllThreadsNamed('NoSuchThread');
    assert.equal(f.length, 0);
  });

  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_();
    assert.deepEqual(['categoryA', 'categoryB'], m.categories);
  });

  test('traceModel_iterateAllEvents', function() {
    var m = createTraceModelWithOneOfEverything();
    var wasCalled = false;
    m.iterateAllEvents(function(event) {
      assert.isTrue(event instanceof tv.c.trace_model.Event);
      wasCalled = true;
    });
    assert.isTrue(wasCalled);
  });

  test('customizeCallback', function() {
    var m = new tv.c.TraceModel();
    m.importTraces([], false, false, function() {
      var browserProcess = m.getOrCreateProcess(1);
      var browserMain = browserProcess.getOrCreateThread(2);
      browserMain.sliceGroup.beginSlice('cat', 'Task', 0);
      browserMain.sliceGroup.beginSlice('cat', 'SubTask', 1);
      browserMain.sliceGroup.endSlice(9);
      browserMain.sliceGroup.endSlice(10);
      browserMain.sliceGroup.beginSlice('cat', 'Task', 20);
      browserMain.sliceGroup.endSlice(30);
    });
    var t2 = m.processes[1].threads[2];
    assert.equal(t2.sliceGroup.length, 3);
    assert.equal(t2.sliceGroup.topLevelSlices.length, 2);
  });

  test('traceModel_sortsSamples', function() {
    var m = new tv.c.TraceModel();
    // The 184, 0 and 185 are the tick-times
    // and irrespective of the order
    // in which the lines appear in the trace,
    // the samples should always be sorted by sampling time.
    m.importTraces(['tick,0x9a,184,0,0x0,5',
                    'tick,0x9b,0,0,0x0,5',
                    'tick,0x9c,185,0,0x0,5']);
    assert.equal(m.samples[0].start, 0);
    assert.equal(m.samples[1].start, 0.184);
    assert.equal(m.samples[2].start, 0.185);
  });

  test('traceModel_sortsGlobalMemoryDumps', function() {
    var m = new tv.c.TraceModel();
    m.importTraces([], true /* shiftWorldToZero */, false, function() {
      m.globalMemoryDumps.push(new tv.c.trace_model.GlobalMemoryDump(m, 1));
      m.globalMemoryDumps.push(new tv.c.trace_model.GlobalMemoryDump(m, 5));
      m.globalMemoryDumps.push(new tv.c.trace_model.GlobalMemoryDump(m, 3));
    });
    assert.equal(m.globalMemoryDumps[0].start, 0);
    assert.equal(m.globalMemoryDumps[1].start, 2);
    assert.equal(m.globalMemoryDumps[2].start, 4);
  });

  test('traceModel_finalizesProcessMemoryDumps', function() {
    var m = new tv.c.TraceModel();
    var p = m.getOrCreateProcess(1);
    m.importTraces([], true /* shiftWorldToZero */, false, function() {
      var g = new tv.c.trace_model.GlobalMemoryDump(m, -1);

      var pmd1 = new tv.c.trace_model.ProcessMemoryDump(g, p, 1);
      p.memoryDumps.push(pmd1);

      var pmd2 = new tv.c.trace_model.ProcessMemoryDump(g, p, 5);
      p.memoryDumps.push(pmd2);

      var pmd3 = new tv.c.trace_model.ProcessMemoryDump(g, p, 3);
      p.memoryDumps.push(pmd3);
      pmd3.vmRegions = [];
    });

    // Check the sort order.
    assert.equal(p.memoryDumps[0].start, 0);
    assert.equal(p.memoryDumps[1].start, 2);
    assert.equal(p.memoryDumps[2].start, 4);

    // Check that the most recent VM regions are linked correctly.
    assert.isUndefined(p.memoryDumps[0].mostRecentVmRegions);
    assert.lengthOf(p.memoryDumps[1].mostRecentVmRegions, 0);
    assert.strictEqual(
        p.memoryDumps[1].mostRecentVmRegions,
        p.memoryDumps[2].mostRecentVmRegions);
  });

  test('traceModel_annotationAddRemove', function() {
    var m = new tv.c.TraceModel();
    var a1 = new tv.c.trace_model.Annotation();
    var a2 = new tv.c.trace_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);
  });
});
</script>
