blob: eaad055b4d31fc0e752f71a6b08f09d920727922 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright 2016 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/unit.html">
<link rel="import" href="/tracing/model/container_memory_dump.html">
<link rel="import" href="/tracing/model/global_memory_dump.html">
<link rel="import" href="/tracing/model/memory_allocator_dump.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">
<script>
'use strict';
/**
* @fileoverview Helper functions for tests involving memory dumps.
*/
tr.exportTo('tr.model', function() {
var GlobalMemoryDump = tr.model.GlobalMemoryDump;
var ProcessMemoryDump = tr.model.ProcessMemoryDump;
var MemoryAllocatorDump = tr.model.MemoryAllocatorDump;
var MemoryAllocatorDumpLink = tr.model.MemoryAllocatorDumpLink;
var VMRegion = tr.model.VMRegion;
var VMRegionClassificationNode = tr.model.VMRegionClassificationNode;
var ScalarNumeric = tr.v.ScalarNumeric;
var sizeInBytes_smallerIsBetter =
tr.b.Unit.byName.sizeInBytes_smallerIsBetter;
var LIGHT = tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;
function castToScalarNumeric(value) {
if (typeof value === 'number')
return new ScalarNumeric(sizeInBytes_smallerIsBetter, value);
assert.instanceOf(value, ScalarNumeric);
return value;
}
function getOption(opt_options, key, opt_defaultValue) {
if (opt_options && (key in opt_options))
return opt_options[key];
else
return opt_defaultValue;
}
function MemoryDumpTestUtils() {
throw new Error('Static class');
}
MemoryDumpTestUtils.SIZE_DELTA = 0.0001;
/**
* Create a new global memory dump and add it to a model.
*
* @param {!tr.Model} model The trace model to which the new global dump
* should be added.
* @param {!{
* ts: (number|undefined),
* duration: (number|undefined),
* levelOfDetail: (!tr.model.ContainerMemoryDump.LevelOfDetail|undefined)
* }=} opt_options Options for creating the new global dump.
* @return {!tr.model.GlobalMemoryDump} The newly created global memory dump.
*/
MemoryDumpTestUtils.addGlobalMemoryDump = function(model, opt_options) {
var timestamp = getOption(opt_options, 'ts', 0);
var gmd = new GlobalMemoryDump(model, timestamp);
gmd.levelOfDetail = getOption(opt_options, 'levelOfDetail', LIGHT);
gmd.duration = getOption(opt_options, 'duration', 0);
model.globalMemoryDumps.push(gmd);
return gmd;
};
/**
* Create a new process memory dump and add it to a global memory dump.
*
* @param {!tr.model.GlobalMemoryDump} gmd The global dump to which the new
* process dump should be added.
* @param {!tr.model.Process} pmd The process associated with the process
* dump.
* @param {!{
* ts: (number|undefined)
* }=} opt_options Options for creating the new process dump.
* @return {!tr.model.ProcessMemoryDump} The newly created process memory
* dump.
*/
MemoryDumpTestUtils.addProcessMemoryDump =
function(gmd, process, opt_options) {
var timestamp = getOption(opt_options, 'ts', gmd.start);
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;
};
/**
* Create a new memory allocator dump.
*
* @param {!tr.model.ContainerMemoryDump} containerDump The container dump
* associated with the new allocator dump.
* @param {string} fullName The full name of the new allocator dump
* (including ancestors).
* @param {!{
* guid: (number|undefined),
* numerics: (!Object<string, (number|!tr.v.ScalarNumeric)>|undefined)
* }=} opt_options Options for creating the new allocator dump.
* @return {!tr.model.MemoryAllocatorDump} The newly created memory allocator
* dump.
*/
MemoryDumpTestUtils.newAllocatorDump = function(
containerDump, fullName, opt_options) {
var dump = new MemoryAllocatorDump(containerDump, fullName,
getOption(opt_options, 'guid'));
var numerics = getOption(opt_options, 'numerics');
if (numerics) {
tr.b.iterItems(numerics, function(numericName, value) {
dump.addNumeric(numericName, castToScalarNumeric(value));
});
}
return dump;
};
/**
* Create a new child memory allocator dump and add it to a parent memory
* allocator dump.
*
* @param {!tr.model.MemoryAllocatorDump} parentDump The parent allocator
* dump.
* @param {string} name The name of the child allocator dump (excluding
* ancestors).
* @param {!{
* guid: (number|undefined),
* numerics: (!Object<string, (number|!tr.v.ScalarNumeric)>|undefined)
* }=} opt_options Options for creating the child allocator dump.
* @return {!tr.model.MemoryAllocatorDump} The newly created child memory
* allocator dump.
*/
MemoryDumpTestUtils.addChildDump = function(parentDump, name, opt_options) {
var childDump = MemoryDumpTestUtils.newAllocatorDump(
parentDump.containerMemoryDump, parentDump.fullName + '/' + name,
opt_options);
childDump.parent = parentDump;
parentDump.children.push(childDump);
return childDump;
};
MemoryDumpTestUtils.addOwnershipLink = function(
ownerDump, ownedDump, opt_importance) {
assert.isUndefined(ownerDump.owns); // Sanity check.
var ownershipLink =
new MemoryAllocatorDumpLink(ownerDump, ownedDump, opt_importance);
ownerDump.owns = ownershipLink;
ownedDump.ownedBy.push(ownershipLink);
return ownershipLink;
};
MemoryDumpTestUtils.checkDumpNumericsAndDiagnostics =
function(dump, expectedNumerics, expectedDiagnostics) {
var actualNumerics = dump.numerics;
assert.sameMembers(
Object.keys(actualNumerics), Object.keys(expectedNumerics));
for (var numericName in actualNumerics) {
var actualNumeric = actualNumerics[numericName];
var expectedNumeric = castToScalarNumeric(expectedNumerics[numericName]);
assert.instanceOf(actualNumeric, tr.v.ScalarNumeric);
assert.strictEqual(actualNumeric.unit, expectedNumeric.unit);
assert.closeTo(actualNumeric.value, expectedNumeric.value,
MemoryDumpTestUtils.SIZE_DELTA);
}
assert.deepEqual(dump.diagnostics, expectedDiagnostics);
};
MemoryDumpTestUtils.checkVMRegions = function(vmRegions, expectedRegions) {
if (vmRegions instanceof VMRegionClassificationNode)
vmRegions = vmRegions.allRegionsForTesting;
var expectedRegionsMap = new Map();
expectedRegions.forEach(function(region) {
if (!(region instanceof VMRegion))
region = VMRegion.fromDict(region);
expectedRegionsMap.set(region.uniqueIdWithinProcess, region);
});
var actualRegionsMap = new Map();
vmRegions.forEach(function(region) {
actualRegionsMap.set(region.uniqueIdWithinProcess, region);
});
assert.strictEqual(actualRegionsMap.size, expectedRegionsMap.size);
for (var id of expectedRegionsMap.keys()) {
var expectedRegion = expectedRegionsMap.get(id);
var actualRegion = actualRegionsMap.get(id);
assert.instanceOf(actualRegion, VMRegion);
assert.strictEqual(actualRegion.startAddress,
expectedRegion.startAddress);
assert.strictEqual(actualRegion.sizeInBytes, expectedRegion.sizeInBytes);
assert.strictEqual(actualRegion.protectionFlags,
expectedRegion.protectionFlags);
assert.strictEqual(actualRegion.mappedFile, expectedRegion.mappedFile);
assert.deepEqual(actualRegion.byteStats, expectedRegion.byteStats);
}
};
return {
MemoryDumpTestUtils: MemoryDumpTestUtils
};
});
</script>