<!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/base/color.html">
<link rel="import" href="/tracing/base/color_scheme.html">
<link rel="import" href="/tracing/core/test_utils.html">
<link rel="import" href="/tracing/model/global_memory_dump.html">
<link rel="import" href="/tracing/model/heap_dump.html">
<link rel="import" href="/tracing/model/memory_dump_test_utils.html">
<link rel="import" href="/tracing/model/process_memory_dump.html">
<link rel="import" href="/tracing/model/vm_region.html">
<link rel="import" href="/tracing/value/numeric.html">
<link rel="import" href="/tracing/value/unit.html">

<script>
'use strict';

/**
 * @fileoverview Helper functions for memory dump analysis sub-view tests.
 */
tr.exportTo('tr.ui.analysis', function() {
  var Color = tr.b.Color;
  var ColorScheme = tr.b.ColorScheme;
  var GlobalMemoryDump = tr.model.GlobalMemoryDump;
  var ProcessMemoryDump = tr.model.ProcessMemoryDump;
  var VMRegion = tr.model.VMRegion;
  var VMRegionClassificationNode = tr.model.VMRegionClassificationNode;
  var ScalarNumeric = tr.v.ScalarNumeric;
  var sizeInBytes_smallerIsBetter =
      tr.v.Unit.byName.sizeInBytes_smallerIsBetter;
  var unitlessNumber_smallerIsBetter =
      tr.v.Unit.byName.unitlessNumber_smallerIsBetter;
  var HeapDump = tr.model.HeapDump;
  var newAllocatorDump = tr.model.MemoryDumpTestUtils.newAllocatorDump;
  var addOwnershipLink = tr.model.MemoryDumpTestUtils.addOwnershipLink;

  function createMultipleTestGlobalMemoryDumps() {
    var model = tr.c.TestUtils.newModel(function(model) {
      var pA = model.getOrCreateProcess(1);
      var pB = model.getOrCreateProcess(2);
      var pC = model.getOrCreateProcess(3);
      var pD = model.getOrCreateProcess(4);

      // ======================================================================
      //   First timestamp.
      // ======================================================================
      var gmd1 = addGlobalMemoryDump(model, 42);

      // Totals and VM regions.
      var pmd1A = addProcessMemoryDump(gmd1, pA, 41);
      pmd1A.totals = { residentBytes: 31457280 /* 30 MiB */ };
      pmd1A.vmRegions = VMRegionClassificationNode.fromRegions([
        VMRegion.fromDict({
          startAddress: 1024,
          sizeInBytes: 20971520, /* 20 MiB */
          protectionFlags: VMRegion.PROTECTION_FLAG_READ,
          mappedFile: '[stack]',
          byteStats: {
            privateDirtyResident: 8388608, /* 8 MiB */
            sharedCleanResident: 12582912, /* 12 MiB */
            proportionalResident: 10485760 /* 10 MiB */
          }
        })
      ]);

      // Everything.
      var pmd1B = addProcessMemoryDump(gmd1, pB, 42);
      pmd1B.totals = {
        residentBytes: 20971520, /* 20 MiB */
        peakResidentBytes: 41943040, /* 40 MiB */
        arePeakResidentBytesResettable: false,
        platformSpecific: {
          private_bytes: 10485760 /* 10 MiB */
        }
      };
      pmd1B.vmRegions = VMRegionClassificationNode.fromRegions([
        VMRegion.fromDict({
          startAddress: 256,
          sizeInBytes: 6000,
          protectionFlags: VMRegion.PROTECTION_FLAG_READ |
              VMRegion.PROTECTION_FLAG_WRITE,
          mappedFile: '[stack:20310]',
          byteStats: {
            proportionalResident: 15728640, /* 15 MiB */
            privateDirtyResident: 1572864, /* 1.5 MiB */
            swapped: 32 /* 32 B */
          }
        }),
        VMRegion.fromDict({
          startAddress: 100000,
          sizeInBytes: 4096,
          protectionFlags: VMRegion.PROTECTION_FLAG_READ,
          mappedFile: '/usr/lib/libwtf.so',
          byteStats: {
            proportionalResident: 4194304, /* 4 MiB */
            privateDirtyResident: 0,
            swapped: 0 /* 32 B */
          }
        })
      ]);
      pmd1B.memoryAllocatorDumps = [
        newAllocatorDump(pmd1B, 'malloc', { size: 3145728 /* 3 MiB */ }),
        newAllocatorDump(pmd1B, 'v8', { size: 5242880 /* 5 MiB */ }),
        newAllocatorDump(pmd1B, 'tracing', {
          size: 1048576 /* 1 MiB */,
          resident_size: 1572864 /* 1.5 MiB */
        })
      ];

      // Allocator dumps only.
      var pmd1C = addProcessMemoryDump(gmd1, pC, 43);
      pmd1C.memoryAllocatorDumps = (function() {
        var oilpanDump = newAllocatorDump(pmd1C, 'oilpan', {
          size: 3221225472 /* 3 GiB */,
          inner_size: 5242880 /* 5 MiB */,
          objects_count: new ScalarNumeric(unitlessNumber_smallerIsBetter, 2015)
        });
        var v8Dump = newAllocatorDump(pmd1C, 'v8', {
          size: 1073741824 /* 1 GiB */,
          inner_size: 2097152 /* 2 MiB */,
          objects_count: new ScalarNumeric(unitlessNumber_smallerIsBetter, 204)
        });

        addOwnershipLink(v8Dump, oilpanDump);

        return [oilpanDump, v8Dump];
      })();
      pmd1C.heapDumps = {
        'v8': (function() {
          var v8HeapDump = new HeapDump(pmd1C, 'v8');
          v8HeapDump.addEntry(
              tr.c.TestUtils.newStackTrace(model,
                  ['V8.Execute', 'UpdateLayoutTree']),
              undefined /* sum over all object types */,
              536870912 /* 512 MiB */);
          return v8HeapDump;
        })()
      };

      // ======================================================================
      //   Second timestamp.
      // ======================================================================
      var gmd2 = addGlobalMemoryDump(model, 68);

      // Everything.
      var pmd2A = addProcessMemoryDump(gmd2, pA, 67);
      pmd2A.totals = { residentBytes: 32505856 /* 31 MiB */ };
      pmd2A.vmRegions = VMRegionClassificationNode.fromRegions([
        VMRegion.fromDict({
          startAddress: 1024,
          sizeInBytes: 20971520, /* 20 MiB */
          protectionFlags: VMRegion.PROTECTION_FLAG_READ,
          mappedFile: '[stack]',
          byteStats: {
            privateDirtyResident: 8388608, /* 8 MiB */
            sharedCleanResident: 11534336, /* 11 MiB */
            proportionalResident: 11534336 /* 11 MiB */
          }
        }),
        VMRegion.fromDict({
          startAddress: 104857600,
          sizeInBytes: 5242880, /* 5 MiB */
          protectionFlags: VMRegion.PROTECTION_FLAG_EXECUTE,
          mappedFile: '/usr/bin/google-chrome',
          byteStats: {
            privateDirtyResident: 0,
            sharedCleanResident: 4194304, /* 4 MiB */
            proportionalResident: 524288 /* 512 KiB */
          }
        })
      ]);
      pmd2A.memoryAllocatorDumps = [
        newAllocatorDump(pmd2A, 'malloc', { size: 9437184 /* 9 MiB */ }),
        newAllocatorDump(pmd2A, 'tracing', {
          size: 2097152 /* 2 MiB */,
          resident_size: 2621440 /* 2.5 MiB */
        })
      ];

      // Totals and allocator dumps only.
      var pmd2B = addProcessMemoryDump(gmd2, pB, 69);
      pmd2B.totals = {
        residentBytes: 19922944, /* 19 MiB */
        peakResidentBytes: 41943040, /* 40 MiB */
        arePeakResidentBytesResettable: false,
        platformSpecific: {
          private_bytes: 8912896 /* 8.5 MiB */
        }
      };
      pmd2B.memoryAllocatorDumps = [
        newAllocatorDump(pmd2B, 'malloc', { size: 2621440 /* 2.5 MiB */ }),
        newAllocatorDump(pmd2B, 'v8', { size: 5242880 /* 5 MiB */ }),
        newAllocatorDump(pmd2B, 'blink', { size: 7340032 /* 7 MiB */ }),
        newAllocatorDump(pmd2B, 'oilpan', { size: 1 }),
        newAllocatorDump(pmd2B, 'tracing', {
          size: 1572864 /* 1.5 MiB */,
          resident_size: 2097152 /* 2 MiB */
        })
      ];

      // Resettable peak total size only.
      var pmd2D = addProcessMemoryDump(gmd2, pD, 71);
      pmd2D.totals = {
        peakResidentBytes: 17825792, /* 17 MiB */
        arePeakResidentBytesResettable: true
      };

      // ======================================================================
      //   Third timestamp.
      // ======================================================================
      var gmd3 = addGlobalMemoryDump(model, 100);

      // Everything.
      var pmd3B = addProcessMemoryDump(gmd3, pB, 102);
      pmd3B.totals = {
        residentBytes: 18874368, /* 18 MiB */
        peakResidentBytes: 44040192, /* 42 MiB */
        arePeakResidentBytesResettable: false,
        platformSpecific: {
          private_bytes: 7340032 /* 7 MiB */
        }
      };
      pmd3B.vmRegions = VMRegionClassificationNode.fromRegions([
        VMRegion.fromDict({
          startAddress: 256,
          sizeInBytes: 6000,
          protectionFlags: VMRegion.PROTECTION_FLAG_READ |
              VMRegion.PROTECTION_FLAG_WRITE,
          mappedFile: '[stack:20310]',
          byteStats: {
            proportionalResident: 21495808, /* 20.5 MiB */
            privateDirtyResident: 524288, /* 0.5 MiB */
            swapped: 64 /* 32 B */
          }
        })
      ]);
      pmd3B.memoryAllocatorDumps = [
        newAllocatorDump(pmd3B, 'malloc', {size: 2883584 /* 2.75 MiB */ }),
        newAllocatorDump(pmd3B, 'v8', { size: 5767168 /* 5.5 MiB */ }),
        newAllocatorDump(pmd3B, 'blink', { size: 6291456 /* 7 MiB */ }),
        newAllocatorDump(pmd3B, 'tracing', {
          size: 2097152 /* 2 MiB */,
          resident_size: 3145728 /* 3 MiB */
        })
      ];

      // Allocator dumps only.
      var pmd3C = addProcessMemoryDump(gmd3, pC, 100);
      pmd3C.memoryAllocatorDumps = (function() {
        var oilpanDump = newAllocatorDump(pmd3C, 'oilpan', {
          size: 3221225472 /* 3 GiB */,
          inner_size: 5242880 /* 5 MiB */,
          objects_count: new ScalarNumeric(unitlessNumber_smallerIsBetter, 2015)
        });
        var v8Dump = newAllocatorDump(pmd3C, 'v8', {
          size: 2147483648 /* 2 GiB */,
          inner_size: 2097152 /* 2 MiB */,
          objects_count: new ScalarNumeric(unitlessNumber_smallerIsBetter, 204)
        });

        addOwnershipLink(v8Dump, oilpanDump);

        return [oilpanDump, v8Dump];
      })();
      pmd3C.heapDumps = {
        'v8': (function() {
          var v8HeapDump = new HeapDump(pmd1C, 'v8');
          v8HeapDump.addEntry(
              tr.c.TestUtils.newStackTrace(model,
                  ['V8.Execute', 'UpdateLayoutTree']),
              undefined /* sum over all object types */,
              268435456 /* 256 MiB */);
          v8HeapDump.addEntry(
              tr.c.TestUtils.newStackTrace(model,
                  ['V8.Execute', 'FrameView::layout']),
              undefined /* sum over all object types */,
              134217728 /* 128 MiB */);
          return v8HeapDump;
        })()
      };

      // Resettable peak total size only.
      var pmd3D = addProcessMemoryDump(gmd3, pD, 99);
      pmd3D.totals = {
        peakResidentBytes: 17825792, /* 17 MiB */
        arePeakResidentBytesResettable: true
      };
    });

    return model.globalMemoryDumps;
  }

  function createSingleTestGlobalMemoryDump() {
    return createMultipleTestGlobalMemoryDumps()[1];
  }

  function createMultipleTestProcessMemoryDumps() {
    return createMultipleTestGlobalMemoryDumps().map(function(gmd) {
      return gmd.processMemoryDumps[2];
    });
  }

  function createSingleTestProcessMemoryDump() {
    return createMultipleTestProcessMemoryDumps()[1];
  }

  function checkNumericFields(row, column, expectedValues, expectedUnit) {
    var fields;
    if (column === undefined)
      fields = row;
    else
      fields = column.fields(row);

    if (expectedValues === undefined) {
      assert.isUndefined(fields);
      return;
    }

    assert.lengthOf(fields, expectedValues.length);
    for (var i = 0; i < fields.length; i++) {
      var field = fields[i];
      var expectedValue = expectedValues[i];
      if (expectedValue === undefined) {
        assert.isUndefined(field);
      } else {
        assert.isDefined(expectedUnit);  // Test sanity check.
        assert.instanceOf(field, ScalarNumeric);
        assert.equal(field.value, expectedValue);
        assert.equal(field.unit, expectedUnit);
      }
    }
  }

  function checkSizeNumericFields(row, column, expectedValues) {
    checkNumericFields(row, column, expectedValues,
        sizeInBytes_smallerIsBetter);
  }

  function checkStringFields(row, column, expectedStrings) {
    var fields = column.fields(row);

    if (expectedStrings === undefined) {
      assert.isUndefined(fields);
      return;
    }

    assert.deepEqual(tr.b.asArray(fields), expectedStrings);
  }

  /**
   * Check the titles, types and aggregation modes of a list of columns.
   * expectedColumns is a list of dictionaries with the following fields:
   *
   *   - title: Either the expected title (string), or a matcher for it
   *     (function that accepts the actual title as its argument).
   *   - type: The expected class of the column.
   *   - noAggregation: If true, the column is expected to have no aggregation
   *     mode (regardless of expectedAggregationMode).
   */
  function checkColumns(columns, expectedColumns, expectedAggregationMode) {
    assert.lengthOf(columns, expectedColumns.length);
    for (var i = 0; i < expectedColumns.length; i++) {
      var actualColumn = columns[i];
      var expectedColumn = expectedColumns[i];
      var expectedTitle = expectedColumn.title;
      if (typeof expectedTitle === 'function')
        expectedTitle(actualColumn.title);  // Custom title matcher.
      else
        assert.strictEqual(actualColumn.title, expectedTitle);  // String title.
      assert.instanceOf(actualColumn, expectedColumn.type);
      assert.strictEqual(actualColumn.aggregationMode,
          expectedColumn.noAggregation ? undefined : expectedAggregationMode);
    }
  }

  function checkColumnInfosAndColor(
      column, fields, contexts, expectedInfos, expectedColorReservedName) {
    // Test sanity checks.
    assert.isDefined(fields);
    if (contexts !== undefined)
      assert.lengthOf(contexts, fields.length);

    // Check infos.
    var infos = [];
    column.addInfos(fields, contexts, infos);
    assert.lengthOf(infos, expectedInfos.length);
    for (var i = 0; i < expectedInfos.length; i++)
      assert.deepEqual(infos[i], expectedInfos[i]);

    // Check color.
    var actualColor = typeof column.color === 'function' ?
        column.color(fields, contexts) :
        column.color;
    checkColor(actualColor, expectedColorReservedName);
  }

  function checkColor(actualColorString, expectedColorReservedName) {
    if (expectedColorReservedName === undefined) {
      assert.isUndefined(actualColorString);
      return;
    }

    var actualColor = Color.fromString(actualColorString);
    var expectedColor = ColorScheme.colors[
        ColorScheme.getColorIdForReservedName(expectedColorReservedName)];
    assert.deepEqual(actualColor, expectedColor);
  }

  function createAndCheckEmptyPanes(
      test, paneTagName, propertyName, opt_callback) {
    // Unset property.
    var unsetViewEl = createTestPane(paneTagName);
    unsetViewEl.rebuild();
    assert.isUndefined(unsetViewEl.createChildPane());
    test.addHTMLOutput(unsetViewEl);

    // Undefined property.
    var undefinedViewEl = createTestPane(paneTagName);
    undefinedViewEl[propertyName] = undefined;
    undefinedViewEl.rebuild();
    assert.isUndefined(undefinedViewEl.createChildPane());
    test.addHTMLOutput(undefinedViewEl);

    // Empty property.
    var emptyViewEl = createTestPane(paneTagName);
    emptyViewEl[propertyName] = [];
    emptyViewEl.rebuild();
    assert.isUndefined(undefinedViewEl.createChildPane());
    test.addHTMLOutput(emptyViewEl);

    // Check that all the panes have the same dimensions.
    var unsetBounds = unsetViewEl.getBoundingClientRect();
    var undefinedBounds = undefinedViewEl.getBoundingClientRect();
    var emptyBounds = emptyViewEl.getBoundingClientRect();
    assert.equal(undefinedBounds.width, unsetBounds.width);
    assert.equal(emptyBounds.width, unsetBounds.width);
    assert.equal(undefinedBounds.height, unsetBounds.height);
    assert.equal(emptyBounds.height, unsetBounds.height);

    // Custom checks (if provided).
    if (opt_callback) {
      opt_callback(unsetViewEl);
      opt_callback(undefinedViewEl);
      opt_callback(emptyViewEl);
    }
  }

  function createTestPane(tagName) {
    var paneEl = document.createElement(tagName);

    // Store a list of requested child panes (for inspection in tests).
    paneEl.requestedChildPanes = [];
    paneEl.addEventListener('request-child-pane-change', function() {
      paneEl.requestedChildPanes.push(paneEl.createChildPane());
    });

    paneEl.createChildPane = function() {
      var childPaneBuilder = this.childPaneBuilder;
      if (childPaneBuilder === undefined)
        return undefined;
      return childPaneBuilder();
    };

    return paneEl;
  }

  function addGlobalMemoryDump(model, timestamp) {
    var gmd = new GlobalMemoryDump(model, timestamp);
    model.globalMemoryDumps.push(gmd);
    return gmd;
  }

  function addProcessMemoryDump(gmd, process, timestamp) {
    var pmd = new ProcessMemoryDump(gmd, process, timestamp);
    process.memoryDumps.push(pmd);
    if (process.pid in gmd.processMemoryDumps) {
      // Test sanity check.
      throw new Error('Process memory dump for process with pid=' +
          process.pid + ' has already been provided');
    }
    gmd.processMemoryDumps[process.pid] = pmd;
    return pmd;
  }

  // TODO(petrcermak): Consider moving this to tracing/ui/base/dom_helpers.html.
  function isElementDisplayed(element) {
    var style = getComputedStyle(element);
    var displayed = style['display'];
    if (displayed === undefined)
      return true;
    return displayed.indexOf('none') === -1;
  }

  /**
   * Convert a list of ContainerMemoryDump(s) to a list of dictionaries of the
   * underlying ProcessMemoryDump(s).
   */
  function convertToProcessMemoryDumps(containerMemoryDumps) {
    return containerMemoryDumps.map(function(containerMemoryDump) {
      return containerMemoryDump.processMemoryDumps;
    });
  }

  /**
   * Extract a chronological list of ProcessMemoryDump(s) (for a given process)
   * from a chronological list of dictionaries of ProcessMemoryDump(s).
   */
  function extractProcessMemoryDumps(processMemoryDumps, pid) {
    return processMemoryDumps.map(function(memoryDumps) {
      return memoryDumps[pid];
    });
  }

  /**
   * Extract a chronological list of lists of VMRegion(s) (for a given process)
   * from a chronological list of dictionaries of ProcessMemoryDump(s).
   */
  function extractVmRegions(processMemoryDumps, pid) {
    return processMemoryDumps.map(function(memoryDumps) {
      var processMemoryDump = memoryDumps[pid];
      if (processMemoryDump === undefined)
        return undefined;
      return processMemoryDump.mostRecentVmRegions;
    });
  }

  /**
   * Extract a chronological list of MemoryAllocatorDump(s) (for a given
   * process and allocator name) from a chronological list of dictionaries of
   * ProcessMemoryDump(s).
   */
  function extractMemoryAllocatorDumps(processMemoryDumps, pid, allocatorName) {
    return processMemoryDumps.map(function(memoryDumps) {
      var processMemoryDump = memoryDumps[pid];
      if (processMemoryDump === undefined)
        return undefined;
      return processMemoryDump.getMemoryAllocatorDumpByFullName(allocatorName);
    });
  }

  /**
   * Extract a chronological list of HeapDump(s) (for a given process and
   * allocator name) from a chronological list of dictionaries of
   * ProcessMemoryDump(s).
   */
  function extractHeapDumps(processMemoryDumps, pid, allocatorName) {
    return processMemoryDumps.map(function(memoryDumps) {
      var processMemoryDump = memoryDumps[pid];
      if (processMemoryDump === undefined ||
          processMemoryDump.heapDumps === undefined)
        return undefined;
      return processMemoryDump.heapDumps[allocatorName];
    });
  }

  return {
    addGlobalMemoryDump: addGlobalMemoryDump,
    addProcessMemoryDump: addProcessMemoryDump,
    createSingleTestGlobalMemoryDump: createSingleTestGlobalMemoryDump,
    createMultipleTestGlobalMemoryDumps: createMultipleTestGlobalMemoryDumps,
    createSingleTestProcessMemoryDump: createSingleTestProcessMemoryDump,
    createMultipleTestProcessMemoryDumps: createMultipleTestProcessMemoryDumps,
    checkNumericFields: checkNumericFields,
    checkSizeNumericFields: checkSizeNumericFields,
    checkStringFields: checkStringFields,
    checkColumns: checkColumns,
    checkColumnInfosAndColor: checkColumnInfosAndColor,
    checkColor: checkColor,
    createAndCheckEmptyPanes: createAndCheckEmptyPanes,
    createTestPane: createTestPane,
    isElementDisplayed: isElementDisplayed,
    convertToProcessMemoryDumps: convertToProcessMemoryDumps,
    extractProcessMemoryDumps: extractProcessMemoryDumps,
    extractVmRegions: extractVmRegions,
    extractMemoryAllocatorDumps: extractMemoryAllocatorDumps,
    extractHeapDumps: extractHeapDumps
  };
});
</script>
