@memlab/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/__tests__/parser/HeapParser.test.d.ts +11 -0
- package/dist/__tests__/parser/HeapParser.test.d.ts.map +1 -0
- package/dist/__tests__/parser/HeapParser.test.js +54 -0
- package/dist/__tests__/parser/NodeHeap.test.d.ts +11 -0
- package/dist/__tests__/parser/NodeHeap.test.d.ts.map +1 -0
- package/dist/__tests__/parser/NodeHeap.test.js +96 -0
- package/dist/__tests__/parser/StringNode.test.d.ts +11 -0
- package/dist/__tests__/parser/StringNode.test.d.ts.map +1 -0
- package/dist/__tests__/parser/StringNode.test.js +61 -0
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.d.ts +16 -0
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.d.ts.map +1 -0
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.js +140 -0
- package/dist/__tests__/utils/utils.test.d.ts +11 -0
- package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils.test.js +81 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/lib/BaseOption.d.ts +31 -0
- package/dist/lib/BaseOption.d.ts.map +1 -0
- package/dist/lib/BaseOption.js +109 -0
- package/dist/lib/BrowserInfo.d.ts +33 -0
- package/dist/lib/BrowserInfo.d.ts.map +1 -0
- package/dist/lib/BrowserInfo.js +117 -0
- package/dist/lib/Config.d.ts +203 -0
- package/dist/lib/Config.d.ts.map +1 -0
- package/dist/lib/Config.js +427 -0
- package/dist/lib/Console.d.ts +67 -0
- package/dist/lib/Console.d.ts.map +1 -0
- package/dist/lib/Console.js +344 -0
- package/dist/lib/Constant.d.ts +38 -0
- package/dist/lib/Constant.d.ts.map +1 -0
- package/dist/lib/Constant.js +58 -0
- package/dist/lib/FileManager.d.ts +69 -0
- package/dist/lib/FileManager.d.ts.map +1 -0
- package/dist/lib/FileManager.js +309 -0
- package/dist/lib/HeapAnalyzer.d.ts +51 -0
- package/dist/lib/HeapAnalyzer.d.ts.map +1 -0
- package/dist/lib/HeapAnalyzer.js +719 -0
- package/dist/lib/HeapParser.d.ts +19 -0
- package/dist/lib/HeapParser.d.ts.map +1 -0
- package/dist/lib/HeapParser.js +128 -0
- package/dist/lib/InternalValueSetter.d.ts +14 -0
- package/dist/lib/InternalValueSetter.d.ts.map +1 -0
- package/dist/lib/InternalValueSetter.js +43 -0
- package/dist/lib/NodeHeap.d.ts +16 -0
- package/dist/lib/NodeHeap.d.ts.map +1 -0
- package/dist/lib/NodeHeap.js +62 -0
- package/dist/lib/ProcessManager.d.ts +25 -0
- package/dist/lib/ProcessManager.d.ts.map +1 -0
- package/dist/lib/ProcessManager.js +67 -0
- package/dist/lib/Serializer.d.ts +49 -0
- package/dist/lib/Serializer.d.ts.map +1 -0
- package/dist/lib/Serializer.js +702 -0
- package/dist/lib/StringLoader.d.ts +26 -0
- package/dist/lib/StringLoader.d.ts.map +1 -0
- package/dist/lib/StringLoader.js +290 -0
- package/dist/lib/Types.d.ts +432 -0
- package/dist/lib/Types.d.ts.map +1 -0
- package/dist/lib/Types.js +11 -0
- package/dist/lib/Utils.d.ts +223 -0
- package/dist/lib/Utils.d.ts.map +1 -0
- package/dist/lib/Utils.js +1736 -0
- package/dist/lib/heap-data/HeapEdge.d.ts +27 -0
- package/dist/lib/heap-data/HeapEdge.d.ts.map +1 -0
- package/dist/lib/heap-data/HeapEdge.js +75 -0
- package/dist/lib/heap-data/HeapLocation.d.ts +22 -0
- package/dist/lib/heap-data/HeapLocation.d.ts.map +1 -0
- package/dist/lib/heap-data/HeapLocation.js +40 -0
- package/dist/lib/heap-data/HeapNode.d.ts +55 -0
- package/dist/lib/heap-data/HeapNode.d.ts.map +1 -0
- package/dist/lib/heap-data/HeapNode.js +344 -0
- package/dist/lib/heap-data/HeapSnapshot.d.ts +85 -0
- package/dist/lib/heap-data/HeapSnapshot.d.ts.map +1 -0
- package/dist/lib/heap-data/HeapSnapshot.js +462 -0
- package/dist/lib/heap-data/HeapStringNode.d.ts +18 -0
- package/dist/lib/heap-data/HeapStringNode.d.ts.map +1 -0
- package/dist/lib/heap-data/HeapStringNode.js +43 -0
- package/dist/lib/heap-data/HeapUtils.d.ts +17 -0
- package/dist/lib/heap-data/HeapUtils.d.ts.map +1 -0
- package/dist/lib/heap-data/HeapUtils.js +25 -0
- package/dist/logger/LeakClusterLogger.d.ts +40 -0
- package/dist/logger/LeakClusterLogger.d.ts.map +1 -0
- package/dist/logger/LeakClusterLogger.js +228 -0
- package/dist/logger/LeakTraceDetailsLogger.d.ts +19 -0
- package/dist/logger/LeakTraceDetailsLogger.d.ts.map +1 -0
- package/dist/logger/LeakTraceDetailsLogger.js +50 -0
- package/dist/modes/BaseMode.d.ts +30 -0
- package/dist/modes/BaseMode.d.ts.map +1 -0
- package/dist/modes/BaseMode.js +95 -0
- package/dist/modes/InteractionTestMode.d.ts +23 -0
- package/dist/modes/InteractionTestMode.d.ts.map +1 -0
- package/dist/modes/InteractionTestMode.js +46 -0
- package/dist/modes/MeasureMode.d.ts +23 -0
- package/dist/modes/MeasureMode.d.ts.map +1 -0
- package/dist/modes/MeasureMode.js +58 -0
- package/dist/modes/RunningModes.d.ts +15 -0
- package/dist/modes/RunningModes.d.ts.map +1 -0
- package/dist/modes/RunningModes.js +40 -0
- package/dist/paths/TraceFinder.d.ts +31 -0
- package/dist/paths/TraceFinder.d.ts.map +1 -0
- package/dist/paths/TraceFinder.js +537 -0
- package/dist/trace-cluster/ClusterUtils.d.ts +14 -0
- package/dist/trace-cluster/ClusterUtils.d.ts.map +1 -0
- package/dist/trace-cluster/ClusterUtils.js +17 -0
- package/dist/trace-cluster/ClusterUtilsHelper.d.ts +38 -0
- package/dist/trace-cluster/ClusterUtilsHelper.d.ts.map +1 -0
- package/dist/trace-cluster/ClusterUtilsHelper.js +373 -0
- package/dist/trace-cluster/ClusteringHeuristics.d.ts +22 -0
- package/dist/trace-cluster/ClusteringHeuristics.d.ts.map +1 -0
- package/dist/trace-cluster/ClusteringHeuristics.js +23 -0
- package/dist/trace-cluster/EvalutationMetric.d.ts +22 -0
- package/dist/trace-cluster/EvalutationMetric.d.ts.map +1 -0
- package/dist/trace-cluster/EvalutationMetric.js +158 -0
- package/dist/trace-cluster/TraceBucket.d.ts +36 -0
- package/dist/trace-cluster/TraceBucket.d.ts.map +1 -0
- package/dist/trace-cluster/TraceBucket.js +238 -0
- package/dist/trace-cluster/TraceElement.d.ts +71 -0
- package/dist/trace-cluster/TraceElement.d.ts.map +1 -0
- package/dist/trace-cluster/TraceElement.js +182 -0
- package/dist/trace-cluster/strategies/TraceAsClusterStrategy.d.ts +15 -0
- package/dist/trace-cluster/strategies/TraceAsClusterStrategy.d.ts.map +1 -0
- package/dist/trace-cluster/strategies/TraceAsClusterStrategy.js +37 -0
- package/dist/trace-cluster/strategies/TraceSimilarityStrategy.d.ts +15 -0
- package/dist/trace-cluster/strategies/TraceSimilarityStrategy.d.ts.map +1 -0
- package/dist/trace-cluster/strategies/TraceSimilarityStrategy.js +60 -0
- package/package.json +60 -0
- package/static/run-meta.json +10 -0
- package/static/visit-order.json +27 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.MemLabConfig = exports.ErrorHandling = void 0;
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const RunningModes_1 = __importDefault(require("../modes/RunningModes"));
|
|
18
|
+
const Console_1 = __importDefault(require("./Console"));
|
|
19
|
+
const Constant_1 = __importDefault(require("./Constant"));
|
|
20
|
+
const FileManager_1 = __importDefault(require("./FileManager"));
|
|
21
|
+
const InternalValueSetter_1 = require("./InternalValueSetter");
|
|
22
|
+
const devices = Constant_1.default.isFRL
|
|
23
|
+
? {}
|
|
24
|
+
: Constant_1.default.isFB
|
|
25
|
+
? require('puppeteer-core/DeviceDescriptors')
|
|
26
|
+
: // eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
27
|
+
require('puppeteer').devices;
|
|
28
|
+
// default viewport config for desktop
|
|
29
|
+
const windowWidth = 1680;
|
|
30
|
+
const windowHeight = 1080;
|
|
31
|
+
const defaultViewport = {
|
|
32
|
+
width: windowWidth,
|
|
33
|
+
height: windowHeight,
|
|
34
|
+
deviceScaleFactor: 1,
|
|
35
|
+
};
|
|
36
|
+
var ErrorHandling;
|
|
37
|
+
(function (ErrorHandling) {
|
|
38
|
+
ErrorHandling[ErrorHandling["Halt"] = 1] = "Halt";
|
|
39
|
+
ErrorHandling[ErrorHandling["Throw"] = 2] = "Throw";
|
|
40
|
+
})(ErrorHandling = exports.ErrorHandling || (exports.ErrorHandling = {}));
|
|
41
|
+
class MemLabConfig {
|
|
42
|
+
constructor(options = {}) {
|
|
43
|
+
// init properties, they can be configured manually
|
|
44
|
+
this.init(options);
|
|
45
|
+
// init built-in properties, they should not be configured manually
|
|
46
|
+
this.initInternalConfigs();
|
|
47
|
+
}
|
|
48
|
+
initInternalConfigs() {
|
|
49
|
+
// DO NOT SET PARAMETER HERE
|
|
50
|
+
this._reportLeaksInTimers = false;
|
|
51
|
+
this._deviceManualOverridden = false;
|
|
52
|
+
this._timerNodes = ['Pending activities'];
|
|
53
|
+
this._timerEdges = [];
|
|
54
|
+
this.targetApp = Constant_1.default.unset;
|
|
55
|
+
this.targetTab = Constant_1.default.unset;
|
|
56
|
+
this.analysisMode = Constant_1.default.unset;
|
|
57
|
+
this.focusFiberNodeId = 1;
|
|
58
|
+
this.isFB = Constant_1.default.isFB;
|
|
59
|
+
// assuming the Evn doesn't support Xvfb before checking
|
|
60
|
+
this.machineSupportsXVFB = false;
|
|
61
|
+
// by default we want to use Xvfb if the Env supports it
|
|
62
|
+
this.useXVFB = true;
|
|
63
|
+
this.specifiedEngine = false;
|
|
64
|
+
// set puppeteer configuration
|
|
65
|
+
this.puppeteerConfig = {
|
|
66
|
+
devtools: this.openDevtoolsConsole,
|
|
67
|
+
// IMPORTANT: test ContinuousTest before change this config
|
|
68
|
+
ignoreHTTPSErrors: true,
|
|
69
|
+
userDataDir: this.userDataDir,
|
|
70
|
+
// Chromium in ContinuousTest needs this args
|
|
71
|
+
args: [
|
|
72
|
+
'--no-sandbox',
|
|
73
|
+
// Disable popup notification
|
|
74
|
+
'--disable-notifications',
|
|
75
|
+
// Automatically allows media stream requests
|
|
76
|
+
'--use-fake-ui-for-media-stream',
|
|
77
|
+
// Feeds fake video stream
|
|
78
|
+
'--use-fake-device-for-media-stream',
|
|
79
|
+
// V8 GC move fewer objects around
|
|
80
|
+
'--js-flags="--no-move-object-start"',
|
|
81
|
+
// Alreay on by default, just want to make sure
|
|
82
|
+
'--enable-precise-memory-info',
|
|
83
|
+
'browser-test',
|
|
84
|
+
],
|
|
85
|
+
defaultViewport,
|
|
86
|
+
};
|
|
87
|
+
// by default don't emulate any device, use the desktop config
|
|
88
|
+
this.emulateDevice = null;
|
|
89
|
+
// the default JS engine of snapshot
|
|
90
|
+
this.jsEngine = Constant_1.default.defaultEngine;
|
|
91
|
+
// the default browser (Chromium)
|
|
92
|
+
this._browser = 'chrome';
|
|
93
|
+
// a set of additional GKs to be enabled
|
|
94
|
+
this.addEnableGK = new Set();
|
|
95
|
+
// a set of additional GKs to be disabled
|
|
96
|
+
this.addDisableGK = new Set();
|
|
97
|
+
// a list of additional QEs to be enabled
|
|
98
|
+
this.qes = [];
|
|
99
|
+
// check if running in ondemand devvm
|
|
100
|
+
this.isOndemand = false;
|
|
101
|
+
// configuration for analyzing external snapshots
|
|
102
|
+
this.useExternalSnapshot = false;
|
|
103
|
+
// new version of heap snapshot has a detachedness field
|
|
104
|
+
this.snapshotHasDetachedness = false;
|
|
105
|
+
// by default running in regular mode
|
|
106
|
+
this.runningMode = RunningModes_1.default.get('regular', this);
|
|
107
|
+
// external heap snapshot paths, if enabled
|
|
108
|
+
this.externalSnapshotFilePaths = [];
|
|
109
|
+
// mute the console output, if enabled
|
|
110
|
+
this.muteConsole = false;
|
|
111
|
+
// log all leak traces, each as an unclassified cluster
|
|
112
|
+
this.logUnclassifiedClusters = false;
|
|
113
|
+
// by default halt the program when utils.haltOrThrow is calleds
|
|
114
|
+
this.errorHandling = ErrorHandling.Halt;
|
|
115
|
+
}
|
|
116
|
+
// initialize configurable parameters
|
|
117
|
+
init(options = {}) {
|
|
118
|
+
// if true dump extra debug info to terminal
|
|
119
|
+
this.verbose = false;
|
|
120
|
+
// dump the web console's output to terminal
|
|
121
|
+
this.dumpWebConsole = false;
|
|
122
|
+
// open dev-tools console when interacting with the page
|
|
123
|
+
this.openDevtoolsConsole = false;
|
|
124
|
+
// clear console, this may eliminate leaks retained by console
|
|
125
|
+
this.clearConsole = false;
|
|
126
|
+
// consider dev-tools console when search for leak trace
|
|
127
|
+
this.traverseDevToolsConsole = true;
|
|
128
|
+
// if true skip all warmup
|
|
129
|
+
this.skipWarmup = false;
|
|
130
|
+
// if true skip all snapshots
|
|
131
|
+
this.skipSnapshot = false;
|
|
132
|
+
// if true skip all screenshots
|
|
133
|
+
this.skipScreenshot = false;
|
|
134
|
+
// if true skip all scrolling
|
|
135
|
+
this.skipScroll = false;
|
|
136
|
+
// if true skip all extra operations on target and final
|
|
137
|
+
this.skipExtraOps = false;
|
|
138
|
+
// if true skip all GC
|
|
139
|
+
this.skipGC = false;
|
|
140
|
+
// true if running in ContinuousTest
|
|
141
|
+
this.isContinuousTest = false;
|
|
142
|
+
// true if running a local test
|
|
143
|
+
this.isTest = false;
|
|
144
|
+
// true if running in local puppeteer mode
|
|
145
|
+
this.isLocalPuppeteer = false;
|
|
146
|
+
// true if pausing on every step
|
|
147
|
+
this.isManualDebug = false;
|
|
148
|
+
// number of warmup repeat in each browser tab instance
|
|
149
|
+
this.warmupRepeat = 2;
|
|
150
|
+
// default waiting time when there is no page load checker callback
|
|
151
|
+
this.delayWhenNoPageLoadCheck = 2000;
|
|
152
|
+
// repeat the intermediate sequence
|
|
153
|
+
this.repeatIntermediateTabs = 1;
|
|
154
|
+
// the # of retries when interaction fails
|
|
155
|
+
this.interactionFailRetry = 1;
|
|
156
|
+
// the # of retries when initial load fails
|
|
157
|
+
this.initialLoadFailRetry = 2;
|
|
158
|
+
// timeout for checking the presence of non-optional click target
|
|
159
|
+
this.presenceCheckTimeout = 120000;
|
|
160
|
+
// default waiting time before exit when exception occurs during page interaction
|
|
161
|
+
this.delayBeforeExitUponException = 120 * 1000;
|
|
162
|
+
// Chrome window width
|
|
163
|
+
this.windowWidth = windowWidth;
|
|
164
|
+
// Chrome window height
|
|
165
|
+
this.windowHeight = windowHeight;
|
|
166
|
+
// disable all scroll
|
|
167
|
+
this.disableScroll = false;
|
|
168
|
+
// default number of scrolls on target page
|
|
169
|
+
this.scrollRepeat = 5;
|
|
170
|
+
// extra waiting time for the target page
|
|
171
|
+
this.extraWaitingForTarget = 0;
|
|
172
|
+
// extra waiting time for the final page
|
|
173
|
+
this.extraWaitingForFinal = 0;
|
|
174
|
+
// if a click operation does not setup a delay, use this delay after click
|
|
175
|
+
this.defaultAfterClickDelay = 2000;
|
|
176
|
+
// delay after garbage collection
|
|
177
|
+
this.waitAfterGC = 1400;
|
|
178
|
+
// delay after checking visual completion
|
|
179
|
+
this.waitAfterPageLoad = 500;
|
|
180
|
+
// delay after browser interaction
|
|
181
|
+
this.waitAfterOperation = 200;
|
|
182
|
+
// timeout for warmup page load (30 seconds)
|
|
183
|
+
this.warmupPageLoadTimeout = 30 * 1000;
|
|
184
|
+
// timeout for initial page load (10 minute)
|
|
185
|
+
this.initialPageLoadTimeout = 10 * 60 * 1000;
|
|
186
|
+
// extra delay after scrolling
|
|
187
|
+
this.waitAfterScrolling = 5000;
|
|
188
|
+
// extra delay after typing
|
|
189
|
+
this.waitAfterTyping = 1000;
|
|
190
|
+
// default repeat for stress testing
|
|
191
|
+
this.stressTestRepeat = 5;
|
|
192
|
+
// only show leaks with detached HTML elements
|
|
193
|
+
this.avoidLeakWithoutDetachedElements = false;
|
|
194
|
+
// if true, hide potential browser memory leak
|
|
195
|
+
this.hideBrowserLeak = true;
|
|
196
|
+
// recursively dump the key object of the WeakMap
|
|
197
|
+
this.chaseWeakMapEdge = true;
|
|
198
|
+
// consider outstanding Fiber nodes from target page as leaks
|
|
199
|
+
this.detectFiberNodeLeak = true;
|
|
200
|
+
// granted permissions to browser, so it won't ask by popping up dialog
|
|
201
|
+
this.grantedPermissions = [
|
|
202
|
+
'geolocation',
|
|
203
|
+
'camera',
|
|
204
|
+
'microphone',
|
|
205
|
+
'accelerometer',
|
|
206
|
+
'gyroscope',
|
|
207
|
+
'magnetometer',
|
|
208
|
+
'payment-handler',
|
|
209
|
+
'background-sync',
|
|
210
|
+
];
|
|
211
|
+
// unbounded growth check only reports objects that are monotonic increasing
|
|
212
|
+
this.monotonicUnboundGrowthOnly = false;
|
|
213
|
+
// object size below the threshold won't be reported
|
|
214
|
+
this.unboundSizeThreshold = 10 * 1024;
|
|
215
|
+
// if true reset the GK list in visit synthesizer
|
|
216
|
+
this.resetGK = false;
|
|
217
|
+
// default userAgent, if undefined use puppeteer's default value
|
|
218
|
+
this.defaultUserAgent = Constant_1.default.defaultUserAgent;
|
|
219
|
+
// dump the heap node information in path summary (focuse mode)
|
|
220
|
+
this.dumpNodeInfo = false;
|
|
221
|
+
// the max steps when doing BFS search for shortest path
|
|
222
|
+
this.maxSearchSteps = Infinity;
|
|
223
|
+
// the max number of outgoing edges to be considered for a single node,
|
|
224
|
+
// when doing BFS search for shortest path
|
|
225
|
+
this.maxSearchReferences = Infinity;
|
|
226
|
+
// the set of nodes to expand one more level in the HTML report
|
|
227
|
+
this.nodeToShowMoreInfo = new Set();
|
|
228
|
+
// if true ignore DevTools console leak
|
|
229
|
+
this.ignoreDevToolsConsoleLeak = false;
|
|
230
|
+
// if true ignore InternalNode when searching for leak trace
|
|
231
|
+
this.ignoreInternalNode = false;
|
|
232
|
+
// node names excluded from the trace finding
|
|
233
|
+
this.nodeNameBlockList = new Set(['system / PropertyCell']);
|
|
234
|
+
// edge names excluded from the trace finding
|
|
235
|
+
this.edgeNameBlockList = new Set(['feedback_cell']);
|
|
236
|
+
// node names less preferable in trace finding
|
|
237
|
+
this.nodeNameGreyList = new Set([
|
|
238
|
+
'InternalNode',
|
|
239
|
+
'Pending activities',
|
|
240
|
+
...Constant_1.default.V8SyntheticRoots,
|
|
241
|
+
]);
|
|
242
|
+
// edge names less preferable in trace finding
|
|
243
|
+
this.edgeNameGreyList = new Set(['alternate', 'firstEffect', 'lastEffect']);
|
|
244
|
+
// browser port for debugging
|
|
245
|
+
this.localBrowserPort = 57305;
|
|
246
|
+
// skip running the following test types in ContinuousTest
|
|
247
|
+
this.ignoreTypesInContinuousTest = new Set();
|
|
248
|
+
// skip running the following apps in ContinuousTest
|
|
249
|
+
this.ignoreAppsInContinuousTest = new Set();
|
|
250
|
+
// a threshold hold to prevent exceeding refer header size limit
|
|
251
|
+
this.URLParamLengthLimit = 400;
|
|
252
|
+
// a set of ignored edges when clustering object shapes
|
|
253
|
+
this.edgeIgnoreSetInShape = new Set(['__proto__', 'map']);
|
|
254
|
+
// a set of ignored nodes when clustering object shapes
|
|
255
|
+
this.nodeIgnoreSetInShape = new Set([
|
|
256
|
+
'(closure)',
|
|
257
|
+
'(array)',
|
|
258
|
+
'(number)',
|
|
259
|
+
'(system)',
|
|
260
|
+
'system / Context',
|
|
261
|
+
'system / Oddball',
|
|
262
|
+
]);
|
|
263
|
+
// if true consider over sized objects as memory leak
|
|
264
|
+
this.oversizeObjectAsLeak = false;
|
|
265
|
+
// if larger than this threshold, consider as memory leak
|
|
266
|
+
this.oversizeThreshold = 0;
|
|
267
|
+
// initialize file and directory paths
|
|
268
|
+
FileManager_1.default.initDirs(this, options);
|
|
269
|
+
}
|
|
270
|
+
getAdditionalConfigInContinuousTest(
|
|
271
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
272
|
+
_app,
|
|
273
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
274
|
+
_interaction) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
// default config instance created from CLI
|
|
278
|
+
static getInstance() {
|
|
279
|
+
if (!MemLabConfig.instance) {
|
|
280
|
+
const config = new MemLabConfig();
|
|
281
|
+
// do not consider objects kept alive by timers as leaks
|
|
282
|
+
config.reportLeaksInTimers = true;
|
|
283
|
+
// assign configuration to console manager
|
|
284
|
+
Console_1.default.setConfig(config);
|
|
285
|
+
// set the singleton
|
|
286
|
+
MemLabConfig.instance = config;
|
|
287
|
+
}
|
|
288
|
+
return MemLabConfig.instance;
|
|
289
|
+
}
|
|
290
|
+
static resetConfigWithTranscientDir() {
|
|
291
|
+
const config = MemLabConfig.getInstance();
|
|
292
|
+
FileManager_1.default.initDirs(config, { transcient: true });
|
|
293
|
+
return config;
|
|
294
|
+
}
|
|
295
|
+
haltOrThrow(msg,
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
297
|
+
secondaryPrintCallback = () => { }) {
|
|
298
|
+
if (this.errorHandling === ErrorHandling.Halt) {
|
|
299
|
+
Console_1.default.error(msg);
|
|
300
|
+
secondaryPrintCallback();
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
throw new Error(msg);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
setTarget(app, tab) {
|
|
308
|
+
this.targetApp = app;
|
|
309
|
+
this.targetTab = tab;
|
|
310
|
+
}
|
|
311
|
+
set scenario(scenario) {
|
|
312
|
+
this._scenario = scenario;
|
|
313
|
+
if (scenario == null) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
// set leak filter
|
|
317
|
+
const { leakFilter, beforeLeakFilter } = scenario;
|
|
318
|
+
if (typeof leakFilter !== 'function') {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
this.externalLeakFilter = { leakFilter };
|
|
322
|
+
// set leak filter init callback
|
|
323
|
+
if (typeof beforeLeakFilter === 'function') {
|
|
324
|
+
this.externalLeakFilter.beforeLeakFilter = beforeLeakFilter;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
get scenario() {
|
|
328
|
+
return this._scenario;
|
|
329
|
+
}
|
|
330
|
+
set isFullRun(isFull) {
|
|
331
|
+
this._isFullRun = isFull;
|
|
332
|
+
}
|
|
333
|
+
get isFullRun() {
|
|
334
|
+
return this._isFullRun;
|
|
335
|
+
}
|
|
336
|
+
set browser(v) {
|
|
337
|
+
if (!Constant_1.default.supportedBrowsers[v]) {
|
|
338
|
+
this.haltOrThrow(`Invalid browser: ${v} ` +
|
|
339
|
+
`(supported browsers: ${Object.keys(Constant_1.default.supportedBrowsers).join(', ')})`);
|
|
340
|
+
}
|
|
341
|
+
this._browser = Constant_1.default.supportedBrowsers[v];
|
|
342
|
+
this.puppeteerConfig.executablePath = this.browserBinaryPath;
|
|
343
|
+
if (this.verbose) {
|
|
344
|
+
Console_1.default.lowLevel(`set browser: ${this.puppeteerConfig.executablePath}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
get browser() {
|
|
348
|
+
return this._browser || 'google-chrome';
|
|
349
|
+
}
|
|
350
|
+
get browserBinaryPath() {
|
|
351
|
+
return path_1.default.join(this.browserDir, this.browser);
|
|
352
|
+
}
|
|
353
|
+
set reportLeaksInTimers(flag) {
|
|
354
|
+
if (typeof flag !== 'boolean') {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (flag) {
|
|
358
|
+
this.removeFromSet(this.nodeNameBlockList, this._timerNodes);
|
|
359
|
+
this.removeFromSet(this.edgeNameBlockList, this._timerEdges);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
this.addToSet(this.nodeNameBlockList, this._timerNodes);
|
|
363
|
+
this.addToSet(this.edgeNameBlockList, this._timerEdges);
|
|
364
|
+
}
|
|
365
|
+
this._reportLeaksInTimers = flag;
|
|
366
|
+
}
|
|
367
|
+
get reportLeaksInTimers() {
|
|
368
|
+
return this._reportLeaksInTimers;
|
|
369
|
+
}
|
|
370
|
+
setDevice(deviceName, options = {}) {
|
|
371
|
+
if (!options.manualOverride && this._deviceManualOverridden) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
this._deviceManualOverridden = !!options.manualOverride;
|
|
375
|
+
// set pc device
|
|
376
|
+
if (deviceName == null || deviceName === 'pc') {
|
|
377
|
+
this.emulateDevice = null;
|
|
378
|
+
this.defaultUserAgent = Constant_1.default.defaultUserAgent;
|
|
379
|
+
this.puppeteerConfig.defaultViewport = defaultViewport;
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
// set mobile device
|
|
383
|
+
const name = deviceName.split('-').join(' ');
|
|
384
|
+
if (!devices[name]) {
|
|
385
|
+
const supportedDevices = Array.from(Object.keys(devices))
|
|
386
|
+
.filter(name => isNaN(parseInt(name, 10)))
|
|
387
|
+
.map(name => name.split(' ').join('-'));
|
|
388
|
+
this.haltOrThrow(`Invalid device: ${name}`, () => {
|
|
389
|
+
Console_1.default.lowLevel(`(supported devies: ${supportedDevices.join(', ')})`);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
this.emulateDevice = devices[name];
|
|
393
|
+
this.puppeteerConfig.defaultViewport = null;
|
|
394
|
+
this.defaultUserAgent = null;
|
|
395
|
+
}
|
|
396
|
+
removeFromSet(set, list) {
|
|
397
|
+
for (const v of list) {
|
|
398
|
+
set.delete(v);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
addToSet(set, list) {
|
|
402
|
+
for (const v of list) {
|
|
403
|
+
set.add(v);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
enableXvfb(display) {
|
|
407
|
+
var _a;
|
|
408
|
+
this.useXVFB = true;
|
|
409
|
+
this.puppeteerConfig.devtools = true;
|
|
410
|
+
(_a = this.puppeteerConfig.args) === null || _a === void 0 ? void 0 : _a.push(`--display=${display}`);
|
|
411
|
+
}
|
|
412
|
+
disableXvfb() {
|
|
413
|
+
const args = [];
|
|
414
|
+
for (const arg of this.puppeteerConfig.args || []) {
|
|
415
|
+
if (!arg.startsWith('--display=')) {
|
|
416
|
+
args.push(arg);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
this.puppeteerConfig.args = args;
|
|
420
|
+
this.puppeteerConfig.devtools = false;
|
|
421
|
+
this.useXVFB = false;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
exports.MemLabConfig = MemLabConfig;
|
|
425
|
+
const config = MemLabConfig.getInstance();
|
|
426
|
+
(0, InternalValueSetter_1.setInternalValue)(config, __filename, Constant_1.default.internalDir);
|
|
427
|
+
exports.default = config;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import { Chalk } from 'chalk';
|
|
11
|
+
import type { MemLabConfig } from './Config';
|
|
12
|
+
import { AnyValue } from './Types';
|
|
13
|
+
interface MemlabConsoleStyles {
|
|
14
|
+
top: (msg: string) => string;
|
|
15
|
+
high: Chalk;
|
|
16
|
+
mid: Chalk;
|
|
17
|
+
low: Chalk;
|
|
18
|
+
success: Chalk;
|
|
19
|
+
error: Chalk;
|
|
20
|
+
warning: Chalk;
|
|
21
|
+
}
|
|
22
|
+
declare class MemLabConsole {
|
|
23
|
+
private config;
|
|
24
|
+
private sections;
|
|
25
|
+
private log;
|
|
26
|
+
private styles;
|
|
27
|
+
private static singleton;
|
|
28
|
+
protected constructor();
|
|
29
|
+
static getInstance(): MemLabConsole;
|
|
30
|
+
private style;
|
|
31
|
+
private init;
|
|
32
|
+
private getLastSection;
|
|
33
|
+
private getLastMsg;
|
|
34
|
+
private logMsg;
|
|
35
|
+
private flushLog;
|
|
36
|
+
private pushMsg;
|
|
37
|
+
private clearPrevMsgInLastSection;
|
|
38
|
+
private clearPrevMsgInSection;
|
|
39
|
+
private clearPrevSection;
|
|
40
|
+
private shouldBeConcise;
|
|
41
|
+
private clearPrevOverwriteMsg;
|
|
42
|
+
private printStr;
|
|
43
|
+
beginSection(name: string): void;
|
|
44
|
+
endSection(name: string): void;
|
|
45
|
+
setConfig(config: MemLabConfig): void;
|
|
46
|
+
table(...args: AnyValue[]): void;
|
|
47
|
+
trace(): void;
|
|
48
|
+
topLevel(msg: string): void;
|
|
49
|
+
highLevel(msg: string): void;
|
|
50
|
+
midLevel(msg: string): void;
|
|
51
|
+
lowLevel(msg: string): void;
|
|
52
|
+
success(msg: string): void;
|
|
53
|
+
criticalError(msg: string): void;
|
|
54
|
+
error(msg: string): void;
|
|
55
|
+
warning(msg: string): void;
|
|
56
|
+
nextLine(): void;
|
|
57
|
+
overwrite(msg: string, options?: {
|
|
58
|
+
level?: keyof MemlabConsoleStyles;
|
|
59
|
+
}): void;
|
|
60
|
+
waitForConsole(query: string): Promise<string>;
|
|
61
|
+
progress(cur: number, total: number, options?: {
|
|
62
|
+
message?: string;
|
|
63
|
+
}): void;
|
|
64
|
+
}
|
|
65
|
+
declare const _default: MemLabConsole;
|
|
66
|
+
export default _default;
|
|
67
|
+
//# sourceMappingURL=Console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Console.d.ts","sourceRoot":"","sources":["../../src/lib/Console.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAc,EAAC,KAAK,EAAC,MAAM,OAAO,CAAC;AAInC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAC,QAAQ,EAAqB,MAAM,SAAS,CAAC;AAmDrD,UAAU,mBAAmB;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7B,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,KAAK,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;CAChB;AAED,cAAM,aAAa;IACjB,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,GAAG,CAAgB;IAC3B,OAAO,CAAC,MAAM,CAQZ;IAEF,OAAO,CAAC,MAAM,CAAC,SAAS,CAAgB;IAExC,SAAS;WAQK,WAAW,IAAI,aAAa;IAiB1C,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,MAAM;IAYd,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,qBAAqB;IAyB7B,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,QAAQ;IAQT,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAahC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAc9B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAIrC,KAAK,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI;IAiBhC,KAAK,IAAI,IAAI;IAOb,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ3B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ5B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ3B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAS1B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMhC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK1B,QAAQ,IAAI,IAAI;IAQhB,SAAS,CACd,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;QAAC,KAAK,CAAC,EAAE,MAAM,mBAAmB,CAAA;KAAM,GAChD,IAAI;IAYA,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc9C,QAAQ,CACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAM,GAC/B,IAAI;CAoBR;;AAED,wBAA2C"}
|