'use strict'; const assert = require('assert'); const { GCProfiler } = require('v8'); function collectGCProfile({ duration }) { return new Promise((resolve) => { const profiler = new GCProfiler(); profiler.start(); setTimeout(() => { resolve(profiler.stop()); }, duration); }); } function checkGCProfile(data) { assert.ok(data.version > 0); assert.ok(data.startTime >= 0); assert.ok(data.endTime >= 0); assert.ok(Array.isArray(data.statistics)); // If the array is not empty, check it if (data.statistics.length) { // Just check the first one const item = data.statistics[0]; assert.ok(typeof item.gcType === 'string'); assert.ok(item.cost >= 0); assert.ok(typeof item.beforeGC === 'object'); assert.ok(typeof item.afterGC === 'object'); // The content of beforeGC and afterGC is same, so we just check afterGC assert.ok(typeof item.afterGC.heapStatistics === 'object'); const heapStatisticsKeys = [ 'externalMemory', 'heapSizeLimit', 'mallocedMemory', 'peakMallocedMemory', 'totalAvailableSize', 'totalGlobalHandlesSize', 'totalHeapSize', 'totalHeapSizeExecutable', 'totalPhysicalSize', 'usedGlobalHandlesSize', 'usedHeapSize', ]; heapStatisticsKeys.forEach((key) => { assert.ok(item.afterGC.heapStatistics[key] >= 0); }); assert.ok(typeof item.afterGC.heapSpaceStatistics === 'object'); const heapSpaceStatisticsKeys = [ 'physicalSpaceSize', 'spaceAvailableSize', 'spaceName', 'spaceSize', 'spaceUsedSize', ]; heapSpaceStatisticsKeys.forEach((key) => { const value = item.afterGC.heapSpaceStatistics[0][key]; assert.ok(key === 'spaceName' ? typeof value === 'string' : value >= 0); }); } } async function testGCProfiler() { const data = await collectGCProfile({ duration: 5000 }); checkGCProfile(data); } module.exports = { collectGCProfile, checkGCProfile, testGCProfiler, };