<!DOCTYPE html>
<!--
Copyright (c) 2015 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/battor_importer.html">
<link rel="import" href="/tracing/extras/importer/linux_perf/ftrace_importer.html">
<link rel="import" href="/tracing/extras/importer/trace_event_importer.html">

<script>
'use strict';

tr.b.unittest.testSuite(function() {

  var CHROMIUM_EVENTS = [
    {
      name: 'a', args: {}, pid: 52, ts: 0,
      cat: 'foo', tid: 53, ph: 'B'
    },
    {
       pid: 94936, tid: 5643, ts: 11000,
       ph: 'c', cat: '__metadata', name: 'clock_sync',
       args: {sync_id: 'ABCDEF-01234-5678-0A1B2C3D', issue_ts: 10000},
       tts: 16496444
    }
  ];

  var BATTOR_LINES = [
    '# BattOr',
    '# voltage_range [0.0, 6144.0] mV',
    '# current_range [0.0, 2275.5] mA',
    '# sample_rate 2000 Hz, gain 5.0x',
    '0.000000 0.000000 4000.000000',
    '0.500000 0.000000 4000.000000',
    '1.000000 0.000000 4000.000000',
    '1.500000 0.000000 4000.000000',
    '2.000000 1.000000 4000.000000'
  ];

  var SYSTRACE_LINES = [
    '# tracer: nop',
    '#',
    '# entries-in-buffer/entries-written: 88819/134210   #P:1',
    '#',
    '#                              _-----=> irqs-off',
    '#                             / _----=> need-resched',
    '#                            | / _---=> hardirq/softirq',
    '#                            || / _--=> preempt-depth',
    '#                            ||| /     delay',
    '#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION',
    '#              | |       |   ||||       |         |',
    'sh-8550  [001] ...1 0.000000: tracing_mark_write: ' +
    'trace_event_clock_sync: name=battor regulator=test_regulator',
    '<8520>-8520  [001] ...1 0.000000: regulator_enable: name=test_regulator',
    '<8520>-8520  [001] ...1 0.000100: regulator_disable: name=test_regulator',
    'sh-8550  [001] ...1     0.001000: tracing_mark_write: ' +
    'trace_event_clock_sync: name=battor regulator=test_regulator'
  ];

  test('canImport', function() {
    assert.isFalse(tr.e.importer.battor.BattorImporter.canImport('string'));
    assert.isFalse(tr.e.importer.battor.BattorImporter.canImport([]));
    assert.isTrue(tr.e.importer.battor.BattorImporter.canImport(
        BATTOR_LINES.join('\n')));
  });

  test('importCrossCorrelationSync', function() {
    var m = tr.c.TestUtils.newModelWithEvents(
        [SYSTRACE_LINES.join('\n'), BATTOR_LINES.join('\n')]);

    assert.isDefined(m.device.powerSeries);

    // Check to see if time shifted correctly
    m.getAllCounters().forEach(function(counter) {
      var series = counter.getSeries(0);
      if (counter.id === 'null.vreg test_regulator enabled')
        assert.equal(series.getTimestamp(0), 2.0);
    });
    assert.equal(m.device.powerSeries.samples[1].start, 0.5);
  });

  test('importExplicitClockSync', function() {
    // Add a BattOr sample with an explicit clock sync.
    var battorLinesWithExplicitSync = BATTOR_LINES;
    battorLinesWithExplicitSync.push(
      '2.500000 1.000000 4000.000000 <ABCDEF-01234-5678-0A1B2C3D>');

    var m = tr.c.TestUtils.newModelWithEvents(
        [CHROMIUM_EVENTS, battorLinesWithExplicitSync.join('\n')]);

    // Check to see if power samples were imported successfully.
    assert.isDefined(m.device.powerSeries);

    // Check to see if the power trace is time shifted correctly.
    assert.equal(m.device.powerSeries.samples[0].start, 7.5);
    assert.equal(m.device.powerSeries.samples[5].start, 10.0);
  });

  test('importMissingLinuxTrace', function() {
    var m = tr.c.TestUtils.newModelWithEvents(BATTOR_LINES.join('\n'));
    assert.isTrue(m.hasImportWarnings);
  });

  test('crossCorrelateWithoutSyncMarkers', function() {
    // Create model.
    var m = new tr.Model();
    var io = new tr.importer.ImportOptions();
    io.showImportWarnings = false;
    m.importOptions = io;

    // Create importer and import power trace.
    var importer = new tr.e.importer.battor.BattorImporter(
        m, BATTOR_LINES.join('\n'));
    var series = new tr.model.PowerSeries(m.device);
    importer.importPowerSamples(series);

    // Check to make sure corrleation sync fails because there are no marks.
    var syncMarks = [];
    assert.isUndefined(importer.correlationClockSync(series, syncMarks));
    assert.isUndefined(m.device.powerSeries);
  });

  test('explicitClockSyncWithoutSyncMarkers', function() {
    // Create an empty model.
    var m = new tr.Model();
    var io = new tr.importer.ImportOptions();
    io.showImportWarnings = false;
    m.importOptions = io;

    // Add a BattOr sample with an explicit clock sync.
    var battorLinesWithExplicitSync = BATTOR_LINES;
    battorLinesWithExplicitSync.push(
      '2.500000 1.000000 4000.000000 <ABCDEF-01234-5678-0A1B2C3D>');

    // Create BattOr importer and import the trace.
    var importer = new tr.e.importer.battor.BattorImporter(
        m, battorLinesWithExplicitSync.join('\n'));
    var series = new tr.model.PowerSeries(m.device);
    importer.importPowerSamples(series);

    // Check to see if explicit clock sync was found by parser.
    assert.isTrue(importer.foundExplicitSyncMark());

    // Check to make sure explicit sync fails because there are no marks.
    var syncMarks = [];
    assert.isUndefined(importer.explicitClockSync(series, syncMarks));
    assert.isUndefined(m.device.powerSeries);
  });

  test('importNotEnoughSamples', function() {
    var m = tr.c.TestUtils.newModelWithEvents(
        BATTOR_LINES.slice(0, 5).join('\n'));
    assert.isTrue(m.hasImportWarnings);
  });
});
</script>
