@memlab/cli 1.0.28 → 1.0.30

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.
Files changed (37) hide show
  1. package/bin/memlab.js +1 -1
  2. package/dist/Dispatcher.d.ts +2 -0
  3. package/dist/Dispatcher.d.ts.map +1 -1
  4. package/dist/Dispatcher.js +30 -1
  5. package/dist/commands/RunMeasureCommand.d.ts.map +1 -1
  6. package/dist/commands/RunMeasureCommand.js +2 -0
  7. package/dist/commands/WarmupAppCommand.d.ts.map +1 -1
  8. package/dist/commands/WarmupAppCommand.js +2 -0
  9. package/dist/commands/heap/DiffLeakCommand.d.ts +2 -0
  10. package/dist/commands/heap/DiffLeakCommand.d.ts.map +1 -1
  11. package/dist/commands/heap/DiffLeakCommand.js +22 -2
  12. package/dist/commands/heap/HeapAnalysisCommand.d.ts +3 -1
  13. package/dist/commands/heap/HeapAnalysisCommand.d.ts.map +1 -1
  14. package/dist/commands/heap/HeapAnalysisCommand.js +33 -14
  15. package/dist/commands/snapshot/TakeSnapshotCommand.d.ts.map +1 -1
  16. package/dist/commands/snapshot/TakeSnapshotCommand.js +2 -0
  17. package/dist/options/e2e/SetChromiumBinaryOption.d.ts.map +1 -1
  18. package/dist/options/e2e/SetChromiumBinaryOption.js +1 -10
  19. package/dist/options/e2e/SetChromiumProtocolTimeoutOption.d.ts +18 -0
  20. package/dist/options/e2e/SetChromiumProtocolTimeoutOption.d.ts.map +1 -0
  21. package/dist/options/e2e/SetChromiumProtocolTimeoutOption.js +46 -0
  22. package/dist/options/experiment/SetControlSnapshotOption.d.ts +20 -0
  23. package/dist/options/experiment/SetControlSnapshotOption.d.ts.map +1 -0
  24. package/dist/options/experiment/SetControlSnapshotOption.js +49 -0
  25. package/dist/options/experiment/SetTreatmentSnapshotOption.d.ts +20 -0
  26. package/dist/options/experiment/SetTreatmentSnapshotOption.d.ts.map +1 -0
  27. package/dist/options/experiment/SetTreatmentSnapshotOption.js +49 -0
  28. package/dist/options/experiment/utils/ExperimentOptionsUtils.d.ts +13 -0
  29. package/dist/options/experiment/utils/ExperimentOptionsUtils.d.ts.map +1 -0
  30. package/dist/options/experiment/utils/ExperimentOptionsUtils.js +33 -0
  31. package/dist/options/heap/HeapAnalysisPluginOption.d.ts +20 -0
  32. package/dist/options/heap/HeapAnalysisPluginOption.d.ts.map +1 -0
  33. package/dist/options/heap/HeapAnalysisPluginOption.js +46 -0
  34. package/dist/options/lib/OptionConstant.d.ts +8 -0
  35. package/dist/options/lib/OptionConstant.d.ts.map +1 -1
  36. package/dist/options/lib/OptionConstant.js +4 -0
  37. package/package.json +5 -5
package/bin/memlab.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node --expose-gc --max-old-space-size=4096
1
+ #!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
2
2
 
3
3
  /**
4
4
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -27,6 +27,8 @@ export declare class CommandDispatcher {
27
27
  protected resetData(): void;
28
28
  dispatch(args: ParsedArgs): Promise<void>;
29
29
  parseOptions(command: BaseCommand, config: MemLabConfig, args: ParsedArgs): Promise<AnyRecord>;
30
+ private mergeConfigFromOptions;
31
+ private mergeArrays;
30
32
  private runCommand;
31
33
  runSubCommandIfAny(command: BaseCommand, args: ParsedArgs, runCmdOpt: RunCommandOptions): Promise<void>;
32
34
  private helper;
@@ -1 +1 @@
1
- {"version":3,"file":"Dispatcher.d.ts","sourceRoot":"","sources":["../src/Dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,SAAS,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AAG1D,OAAO,WAAW,MAAM,eAAe,CAAC;AAGxC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,KAAK,iBAAiB,GAAG;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,SAAS,CAAC;CAC9B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAIF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,qBAAqB,CAAgB;gBAEjC,OAAO,GAAE,wBAA6B;IAOlD,SAAS,CAAC,SAAS;IAKb,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BzC,YAAY,CAChB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,SAAS,CAAC;YAYP,UAAU;IAiDlB,kBAAkB,CACtB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC;YA4BF,MAAM;CAWrB;;AAED,wBAAuC"}
1
+ {"version":3,"file":"Dispatcher.d.ts","sourceRoot":"","sources":["../src/Dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,SAAS,EAAY,YAAY,EAAW,MAAM,cAAc,CAAC;AAG9E,OAAO,WAAW,MAAM,eAAe,CAAC;AAGxC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,KAAK,iBAAiB,GAAG;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,SAAS,CAAC;CAC9B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAIF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,qBAAqB,CAAgB;gBAEjC,OAAO,GAAE,wBAA6B;IAOlD,SAAS,CAAC,SAAS;IAKb,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BzC,YAAY,CAChB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,SAAS,CAAC;IAYrB,OAAO,CAAC,sBAAsB;IAgB9B,OAAO,CAAC,WAAW;YAaL,UAAU;IAiDlB,kBAAkB,CACtB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC;YA4BF,MAAM;CAWrB;;AAED,wBAAuC"}
@@ -77,12 +77,41 @@ class CommandDispatcher {
77
77
  for (const option of options) {
78
78
  const ret = yield option.run(config, args);
79
79
  if (ret) {
80
- Object.assign(configFromOptions, ret);
80
+ this.mergeConfigFromOptions(configFromOptions, ret);
81
81
  }
82
82
  }
83
83
  return configFromOptions;
84
84
  });
85
85
  }
86
+ mergeConfigFromOptions(to, from) {
87
+ for (const key in from) {
88
+ if (Array.isArray(to[key]) && Array.isArray(from[key])) {
89
+ // both are arrays, merge them
90
+ this.mergeArrays(to[key], from[key]);
91
+ }
92
+ else if (from[key] == null || to[key] == null) {
93
+ // one of them is null, use the other one
94
+ to[key] = to[key] || from[key];
95
+ }
96
+ else {
97
+ // both have existing values, first one wins
98
+ core_1.info.warning(`Merge conflict CLI options key: ${key}`);
99
+ }
100
+ }
101
+ return to;
102
+ }
103
+ mergeArrays(arr1, arr2) {
104
+ if (arr1 == null) {
105
+ return arr2;
106
+ }
107
+ if (arr2 == null) {
108
+ return arr1;
109
+ }
110
+ for (const v of arr2) {
111
+ arr1.push(v);
112
+ }
113
+ return arr1;
114
+ }
86
115
  runCommand(command, args, runCmdOpt = { configFromOptions: {} }) {
87
116
  var _a;
88
117
  return __awaiter(this, void 0, void 0, function* () {
@@ -1 +1 @@
1
- {"version":3,"file":"RunMeasureCommand.d.ts","sourceRoot":"","sources":["../../src/commands/RunMeasureCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAEnE,OAAO,WAAW,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAgB,UAAU,EAAC,MAAM,cAAc,CAAC;AAwBvD,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,WAAW;IACxD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,WAAW,EAAE;IAIjC,WAAW,IAAI,oBAAoB,EAAE;IAQrC,UAAU,IAAI,UAAU,EAAE;IAyBpB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAS9C"}
1
+ {"version":3,"file":"RunMeasureCommand.d.ts","sourceRoot":"","sources":["../../src/commands/RunMeasureCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAEnE,OAAO,WAAW,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAgB,UAAU,EAAC,MAAM,cAAc,CAAC;AAyBvD,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,WAAW;IACxD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,WAAW,EAAE;IAIjC,WAAW,IAAI,oBAAoB,EAAE;IAQrC,UAAU,IAAI,UAAU,EAAE;IA0BpB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAS9C"}
@@ -46,6 +46,7 @@ const DisableWebSecurityOption_1 = __importDefault(require("../options/e2e/Disab
46
46
  const EnableJSRewriteOption_1 = __importDefault(require("../options/e2e/EnableJSRewriteOption"));
47
47
  const EnableJSInterceptOption_1 = __importDefault(require("../options/e2e/EnableJSInterceptOption"));
48
48
  const SetChromiumBinaryOption_1 = __importDefault(require("../options/e2e/SetChromiumBinaryOption"));
49
+ const SetChromiumProtocolTimeoutOption_1 = __importDefault(require("../options/e2e/SetChromiumProtocolTimeoutOption"));
49
50
  class RunMeasureCommand extends BaseCommand_1.default {
50
51
  getCommandName() {
51
52
  return 'measure';
@@ -79,6 +80,7 @@ class RunMeasureCommand extends BaseCommand_1.default {
79
80
  new RemoteBrowserDebugOption_1.default(),
80
81
  new ScenarioFileOption_1.default(),
81
82
  new SetChromiumBinaryOption_1.default(),
83
+ new SetChromiumProtocolTimeoutOption_1.default(),
82
84
  new SetDeviceOption_1.default(),
83
85
  new SetUserAgentOption_1.default(),
84
86
  new DisableXvfbOption_1.default(),
@@ -1 +1 @@
1
- {"version":3,"file":"WarmupAppCommand.d.ts","sourceRoot":"","sources":["../../src/commands/WarmupAppCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,WAAW,MAAM,gBAAgB,CAAC;AAmBzC,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,WAAW;IACzD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,WAAW,EAAE;IAIjC,WAAW,IAAI,oBAAoB,EAAE;IAOrC,UAAU,IAAI,UAAU,EAAE;IAoBpB,GAAG,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
1
+ {"version":3,"file":"WarmupAppCommand.d.ts","sourceRoot":"","sources":["../../src/commands/WarmupAppCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,WAAW,MAAM,gBAAgB,CAAC;AAoBzC,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,WAAW;IACzD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,WAAW,EAAE;IAIjC,WAAW,IAAI,oBAAoB,EAAE;IAOrC,UAAU,IAAI,UAAU,EAAE;IAqBpB,GAAG,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
@@ -39,6 +39,7 @@ const DisableWebSecurityOption_1 = __importDefault(require("../options/e2e/Disab
39
39
  const EnableJSRewriteOption_1 = __importDefault(require("../options/e2e/EnableJSRewriteOption"));
40
40
  const EnableJSInterceptOption_1 = __importDefault(require("../options/e2e/EnableJSInterceptOption"));
41
41
  const SetChromiumBinaryOption_1 = __importDefault(require("../options/e2e/SetChromiumBinaryOption"));
42
+ const SetChromiumProtocolTimeoutOption_1 = __importDefault(require("../options/e2e/SetChromiumProtocolTimeoutOption"));
42
43
  class FBWarmupAppCommand extends BaseCommand_1.default {
43
44
  getCommandName() {
44
45
  return 'warmup';
@@ -64,6 +65,7 @@ class FBWarmupAppCommand extends BaseCommand_1.default {
64
65
  new RemoteBrowserDebugOption_1.default(),
65
66
  new ScenarioFileOption_1.default(),
66
67
  new SetChromiumBinaryOption_1.default(),
68
+ new SetChromiumProtocolTimeoutOption_1.default(),
67
69
  new SetDeviceOption_1.default(),
68
70
  new SetUserAgentOption_1.default(),
69
71
  new DisableXvfbOption_1.default(),
@@ -26,7 +26,9 @@ export default class CheckLeakCommand extends BaseCommand {
26
26
  getCategory(): CommandCategory;
27
27
  getPrerequisites(): BaseCommand[];
28
28
  getOptions(): BaseOption[];
29
+ protected showWorkingDirErrorMessageAndHalt(): never;
29
30
  protected getWorkDirs(options: CLIOptions): WorkDirSettings;
31
+ private dumpVerboseInfo;
30
32
  run(options: CLIOptions): Promise<void>;
31
33
  }
32
34
  //# sourceMappingURL=DiffLeakCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DiffLeakCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/heap/DiffLeakCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,oBAAoB,CAAC;AAGhE,OAAO,WAAW,EAAE,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAiB/D,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,WAAW;IACvD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,0BAA0B,CAAS;IAE3C,SAAS,CAAC,6BAA6B,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAOlE,SAAS,CAAC,iCAAiC,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;gBAM1D,OAAO,GAAE,uBAA4B;IAKjD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,WAAW,IAAI,eAAe;IAI9B,gBAAgB,IAAI,WAAW,EAAE;IAIjC,UAAU,IAAI,UAAU,EAAE;IAkB1B,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,eAAe;IAsBrD,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAa9C"}
1
+ {"version":3,"file":"DiffLeakCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/heap/DiffLeakCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,oBAAoB,CAAC;AAGhE,OAAO,WAAW,EAAE,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAmB/D,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,WAAW;IACvD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,0BAA0B,CAAS;IAE3C,SAAS,CAAC,6BAA6B,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAOlE,SAAS,CAAC,iCAAiC,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;gBAM1D,OAAO,GAAE,uBAA4B;IAKjD,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,WAAW,IAAI,eAAe;IAI9B,gBAAgB,IAAI,WAAW,EAAE;IAIjC,UAAU,IAAI,UAAU,EAAE;IAoB1B,SAAS,CAAC,iCAAiC,IAAI,KAAK;IAYpD,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,eAAe;IAqB3D,OAAO,CAAC,eAAe;IAejB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAc9C"}
@@ -52,6 +52,8 @@ const SetControlWorkDirOption_1 = __importDefault(require("../../options/experim
52
52
  const SetTreatmentWorkDirOption_1 = __importDefault(require("../../options/experiment/SetTreatmentWorkDirOption"));
53
53
  const SetMaxClusterSampleSizeOption_1 = __importDefault(require("../../options/SetMaxClusterSampleSizeOption"));
54
54
  const SetTraceContainsFilterOption_1 = __importDefault(require("../../options/heap/SetTraceContainsFilterOption"));
55
+ const SetControlSnapshotOption_1 = __importDefault(require("../../options/experiment/SetControlSnapshotOption"));
56
+ const SetTreatmentSnapshotOption_1 = __importDefault(require("../../options/experiment/SetTreatmentSnapshotOption"));
55
57
  class CheckLeakCommand extends BaseCommand_1.default {
56
58
  useDefaultMLClusteringSetting(cliArgs) {
57
59
  if (!MLClusteringOption_1.default.hasOptionSet(cliArgs)) {
@@ -84,7 +86,9 @@ class CheckLeakCommand extends BaseCommand_1.default {
84
86
  }
85
87
  getOptions() {
86
88
  return [
89
+ new SetControlSnapshotOption_1.default(),
87
90
  new SetControlWorkDirOption_1.default(),
91
+ new SetTreatmentSnapshotOption_1.default(),
88
92
  new SetTreatmentWorkDirOption_1.default(),
89
93
  new JSEngineOption_1.default(),
90
94
  new LeakFilterFileOption_1.default(),
@@ -99,13 +103,21 @@ class CheckLeakCommand extends BaseCommand_1.default {
99
103
  new SetTraceContainsFilterOption_1.default(),
100
104
  ];
101
105
  }
106
+ showWorkingDirErrorMessageAndHalt() {
107
+ throw core_1.utils.haltOrThrow('No control or test working directory or snapshot location specified, ' +
108
+ 'please specify them via: \n' +
109
+ ` --${new SetControlSnapshotOption_1.default().getOptionName()} with ` +
110
+ ` --${new SetTreatmentSnapshotOption_1.default().getOptionName()}\n` +
111
+ 'alternatively, you can also specify them via: \n' +
112
+ ` --${new SetControlWorkDirOption_1.default().getOptionName()} with ` +
113
+ ` --${new SetTreatmentWorkDirOption_1.default().getOptionName()}`);
114
+ }
102
115
  getWorkDirs(options) {
103
116
  var _a, _b;
104
117
  // double check parameters
105
118
  if (!((_a = options.configFromOptions) === null || _a === void 0 ? void 0 : _a.controlWorkDirs) ||
106
119
  !((_b = options.configFromOptions) === null || _b === void 0 ? void 0 : _b.treatmentWorkDirs)) {
107
- core_1.info.error('Please specify control and test working directory');
108
- throw core_1.utils.haltOrThrow('No control or test working directory specified');
120
+ this.showWorkingDirErrorMessageAndHalt();
109
121
  }
110
122
  // get parameters
111
123
  const controlWorkDirs = options.configFromOptions['controlWorkDirs'];
@@ -115,6 +127,13 @@ class CheckLeakCommand extends BaseCommand_1.default {
115
127
  treatmentWorkDirs,
116
128
  };
117
129
  }
130
+ dumpVerboseInfo(controlWorkDirs, treatmentWorkDirs) {
131
+ if (core_1.config.verbose) {
132
+ core_1.info.lowLevel(`control working directories: ${controlWorkDirs.join(', ')}`);
133
+ core_1.info.lowLevel(`treatment working directories: ${treatmentWorkDirs.join(', ')}`);
134
+ core_1.info.lowLevel(`diffing working directory: ${treatmentWorkDirs[0]}`);
135
+ }
136
+ }
118
137
  run(options) {
119
138
  return __awaiter(this, void 0, void 0, function* () {
120
139
  core_1.config.chaseWeakMapEdge = false;
@@ -124,6 +143,7 @@ class CheckLeakCommand extends BaseCommand_1.default {
124
143
  workDir: treatmentWorkDirs[0],
125
144
  silentFail: true,
126
145
  });
146
+ this.dumpVerboseInfo(controlWorkDirs, treatmentWorkDirs);
127
147
  // diff memory leaks
128
148
  this.useDefaultMLClusteringSetting(options.cliArgs);
129
149
  yield core_1.analysis.diffLeakByWorkDir({ controlWorkDirs, treatmentWorkDirs });
@@ -7,15 +7,17 @@
7
7
  * @format
8
8
  * @oncall web_perf_infra
9
9
  */
10
- import type { CLIOptions, CommandOptionExample } from '@memlab/core';
10
+ import type { BaseOption, CLIOptions, CommandOptionExample } from '@memlab/core';
11
11
  import BaseCommand, { CommandCategory } from '../../BaseCommand';
12
12
  export default class RunHeapAnalysisCommand extends BaseCommand {
13
13
  getCommandName(): string;
14
14
  getDescription(): string;
15
15
  getCategory(): CommandCategory;
16
16
  getPrerequisites(): BaseCommand[];
17
+ getOptions(): BaseOption[];
17
18
  getSubCommands(): BaseCommand[];
18
19
  getExamples(): CommandOptionExample[];
20
+ private errorIfNoSubCommand;
19
21
  run(options: CLIOptions): Promise<void>;
20
22
  }
21
23
  //# sourceMappingURL=HeapAnalysisCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"HeapAnalysisCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/heap/HeapAnalysisCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAGnE,OAAO,WAAW,EAAE,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAO/D,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,WAAW;IAC7D,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,WAAW,IAAI,eAAe;IAI9B,gBAAgB,IAAI,WAAW,EAAE;IAIjC,cAAc,IAAI,WAAW,EAAE;IAU/B,WAAW,IAAI,oBAAoB,EAAE;IAI/B,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAqB9C"}
1
+ {"version":3,"file":"HeapAnalysisCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/heap/HeapAnalysisCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAG/E,OAAO,WAAW,EAAE,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAS/D,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,WAAW;IAC7D,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,WAAW,IAAI,eAAe;IAI9B,gBAAgB,IAAI,WAAW,EAAE;IAIjC,UAAU,IAAI,UAAU,EAAE;IAI1B,cAAc,IAAI,WAAW,EAAE;IAU/B,WAAW,IAAI,oBAAoB,EAAE;YAIvB,mBAAmB;IAwB3B,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAc9C"}
@@ -50,12 +50,13 @@ const heap_analysis_1 = require("@memlab/heap-analysis");
50
50
  const HeapAnalysisSubCommandWrapper_1 = __importDefault(require("./HeapAnalysisSubCommandWrapper"));
51
51
  const HelperCommand_1 = __importDefault(require("../helper/HelperCommand"));
52
52
  const InitDirectoryCommand_1 = __importDefault(require("../InitDirectoryCommand"));
53
+ const HeapAnalysisPluginOption_1 = __importDefault(require("../../options/heap/HeapAnalysisPluginOption"));
53
54
  class RunHeapAnalysisCommand extends BaseCommand_1.default {
54
55
  getCommandName() {
55
56
  return 'analyze';
56
57
  }
57
58
  getDescription() {
58
- return 'Run heap analysis plugins';
59
+ return 'Run heap analysis on heap snapshots.\n';
59
60
  }
60
61
  getCategory() {
61
62
  return BaseCommand_1.CommandCategory.COMMON;
@@ -63,6 +64,9 @@ class RunHeapAnalysisCommand extends BaseCommand_1.default {
63
64
  getPrerequisites() {
64
65
  return [new InitDirectoryCommand_1.default()];
65
66
  }
67
+ getOptions() {
68
+ return [new HeapAnalysisPluginOption_1.default()];
69
+ }
66
70
  getSubCommands() {
67
71
  const analyses = [...heap_analysis_1.heapAnalysisLoader.loadAllAnalysis().values()];
68
72
  return analyses.map((analysis) => {
@@ -75,23 +79,38 @@ class RunHeapAnalysisCommand extends BaseCommand_1.default {
75
79
  getExamples() {
76
80
  return ['<PLUGIN_NAME> [PLUGIN_OPTIONS]'];
77
81
  }
82
+ errorIfNoSubCommand(args, analysisMap) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ if (args && args._.length >= 2 && analysisMap.has(args._[1])) {
85
+ return;
86
+ }
87
+ const helper = new HelperCommand_1.default();
88
+ const modules = new Map();
89
+ for (const subCommand of this.getSubCommands()) {
90
+ modules.set(subCommand.getCommandName(), subCommand);
91
+ }
92
+ const errMsg = args && args._.length < 2
93
+ ? `\n Heap analysis plugin name missing\n`
94
+ : `\n Invalid command \`memlab ${this.getCommandName()} ${args === null || args === void 0 ? void 0 : args._[1]}\`\n`;
95
+ core_1.info.error(errMsg);
96
+ yield helper.run({ cliArgs: args, modules, command: this });
97
+ core_1.utils.haltOrThrow(errMsg, { printErrorBeforeHalting: false });
98
+ });
99
+ }
78
100
  run(options) {
101
+ var _a;
79
102
  return __awaiter(this, void 0, void 0, function* () {
103
+ // process command line arguments and load analysis modules
80
104
  const args = options.cliArgs;
81
- const analysisMap = heap_analysis_1.heapAnalysisLoader.loadAllAnalysis();
82
- if (!args || args._.length < 2 || !analysisMap.has(args._[1])) {
83
- const helper = new HelperCommand_1.default();
84
- const modules = new Map();
85
- for (const subCommand of this.getSubCommands()) {
86
- modules.set(subCommand.getCommandName(), subCommand);
87
- }
88
- const errMsg = args && args._.length < 2
89
- ? `\n Heap analysis plugin name missing\n`
90
- : `\n Invalid command \`memlab ${this.getCommandName()} ${args === null || args === void 0 ? void 0 : args._[1]}\`\n`;
91
- core_1.info.error(errMsg);
92
- yield helper.run({ cliArgs: args, modules, command: this });
93
- core_1.utils.haltOrThrow(errMsg, { printErrorBeforeHalting: false });
105
+ let plugin = (_a = options.configFromOptions) === null || _a === void 0 ? void 0 : _a.heapAnalysisPlugin;
106
+ if (plugin != null) {
107
+ plugin = `${plugin}`;
94
108
  }
109
+ const analysisMap = heap_analysis_1.heapAnalysisLoader.loadAllAnalysis({
110
+ heapAnalysisPlugin: plugin,
111
+ errorWhenPluginFailed: true,
112
+ });
113
+ yield this.errorIfNoSubCommand(args, analysisMap);
95
114
  });
96
115
  }
97
116
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TakeSnapshotCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/snapshot/TakeSnapshotCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAEnE,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAG5C,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAwBxC,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,WAAW;IAC1D,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,WAAW,EAAE;IAQjC,WAAW,IAAI,oBAAoB,EAAE;IAQrC,UAAU,IAAI,UAAU,EAAE;IA0BpB,GAAG,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
1
+ {"version":3,"file":"TakeSnapshotCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/snapshot/TakeSnapshotCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAEnE,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAG5C,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAyBxC,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,WAAW;IAC1D,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,WAAW,EAAE;IAQjC,WAAW,IAAI,oBAAoB,EAAE;IAQrC,UAAU,IAAI,UAAU,EAAE;IA2BpB,GAAG,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
@@ -46,6 +46,7 @@ const EnableJSRewriteOption_1 = __importDefault(require("../../options/e2e/Enabl
46
46
  const EnableJSInterceptOption_1 = __importDefault(require("../../options/e2e/EnableJSInterceptOption"));
47
47
  const TargetWorkerOption_1 = __importDefault(require("../../options/e2e/TargetWorkerOption"));
48
48
  const SetChromiumBinaryOption_1 = __importDefault(require("../../options/e2e/SetChromiumBinaryOption"));
49
+ const SetChromiumProtocolTimeoutOption_1 = __importDefault(require("../../options/e2e/SetChromiumProtocolTimeoutOption"));
49
50
  class TakeSnapshotCommand extends BaseCommand_1.default {
50
51
  getCommandName() {
51
52
  return 'snapshot';
@@ -82,6 +83,7 @@ class TakeSnapshotCommand extends BaseCommand_1.default {
82
83
  new RemoteBrowserDebugOption_1.default(),
83
84
  new ScenarioFileOption_1.default(),
84
85
  new SetChromiumBinaryOption_1.default(),
86
+ new SetChromiumProtocolTimeoutOption_1.default(),
85
87
  new SetDeviceOption_1.default(),
86
88
  new SetUserAgentOption_1.default(),
87
89
  new DisableXvfbOption_1.default(),
@@ -1 +1 @@
1
- {"version":3,"file":"SetChromiumBinaryOption.d.ts","sourceRoot":"","sources":["../../../src/options/e2e/SetChromiumBinaryOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAI1C,OAAO,EAAc,UAAU,EAAC,MAAM,cAAc,CAAC;AAGrD,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIlB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAgBnE"}
1
+ {"version":3,"file":"SetChromiumBinaryOption.d.ts","sourceRoot":"","sources":["../../../src/options/e2e/SetChromiumBinaryOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAQ,UAAU,EAAC,MAAM,cAAc,CAAC;AAG/C,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIlB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAOnE"}
@@ -12,8 +12,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const path_1 = __importDefault(require("path"));
16
- const fs_1 = __importDefault(require("fs"));
17
15
  const core_1 = require("@memlab/core");
18
16
  const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
19
17
  class SetChromiumBinaryOption extends core_1.BaseOption {
@@ -28,14 +26,7 @@ class SetChromiumBinaryOption extends core_1.BaseOption {
28
26
  const name = this.getOptionName();
29
27
  const arg = args[name];
30
28
  if (arg) {
31
- const binaryPath = path_1.default.resolve(process.cwd(), arg);
32
- if (!fs_1.default.existsSync(binaryPath)) {
33
- throw core_1.utils.haltOrThrow(`Chromium binary does not exist: ${binaryPath}`);
34
- }
35
- if (config.verbose) {
36
- core_1.info.lowLevel(`Using ${binaryPath} as Chromium binary for E2E run`);
37
- }
38
- config.puppeteerConfig.executablePath = binaryPath;
29
+ core_1.utils.setChromiumBinary(config, arg);
39
30
  }
40
31
  });
41
32
  }
@@ -0,0 +1,18 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class SetChromiumProtocolTimeoutOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=SetChromiumProtocolTimeoutOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SetChromiumProtocolTimeoutOption.d.ts","sourceRoot":"","sources":["../../../src/options/e2e/SetChromiumProtocolTimeoutOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAc,UAAU,EAAC,MAAM,cAAc,CAAC;AAGrD,MAAM,CAAC,OAAO,OAAO,gCAAiC,SAAQ,UAAU;IACtE,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAUlB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBnE"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
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
+ const core_1 = require("@memlab/core");
16
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
17
+ class SetChromiumProtocolTimeoutOption extends core_1.BaseOption {
18
+ getOptionName() {
19
+ return OptionConstant_1.default.optionNames.CHROMIUM_PROTOCOL_TIMEOUT;
20
+ }
21
+ getDescription() {
22
+ return ('set the protocol timeout for chromium connection (in ms). \n' +
23
+ 'The current default value is 180000, you may want to increase the ' +
24
+ 'timeout via this flag when the heap snapshot is ' +
25
+ 'too big (e.g., over 1GB) and the Page crashed with error: ' +
26
+ "'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'.");
27
+ }
28
+ parse(config, args) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ const name = this.getOptionName();
31
+ const arg = args[name];
32
+ if (arg) {
33
+ const timeout = parseInt(arg, 10);
34
+ if (Number.isNaN(timeout)) {
35
+ core_1.utils.haltOrThrow(`Invalid Chromium protocol timeout value: ${arg}. ` +
36
+ 'It must be a number.');
37
+ }
38
+ if (config.verbose) {
39
+ core_1.info.lowLevel(`Set Chromium protocol timeout to ${timeout}.`);
40
+ }
41
+ config.puppeteerConfig.protocolTimeout = timeout;
42
+ }
43
+ });
44
+ }
45
+ }
46
+ exports.default = SetChromiumProtocolTimeoutOption;
@@ -0,0 +1,20 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { MemLabConfig, Nullable } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class SetControlWorkDirOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<{
17
+ controlWorkDirs?: Nullable<string[]>;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=SetControlSnapshotOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SetControlSnapshotOption.d.ts","sourceRoot":"","sources":["../../../src/options/experiment/SetControlSnapshotOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAC,UAAU,EAAO,MAAM,cAAc,CAAC;AAO9C,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,UAAU;IAC7D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIlB,KAAK,CACT,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;QAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;KAAC,CAAC;CAYnD"}
@@ -0,0 +1,49 @@
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
+ * @format
9
+ * @oncall web_perf_infra
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ const ExperimentOptionsUtils_1 = require("./utils/ExperimentOptionsUtils");
27
+ class SetControlWorkDirOption extends core_1.BaseOption {
28
+ getOptionName() {
29
+ return OptionConstant_1.default.optionNames.CONTROL_SNAPSHOT;
30
+ }
31
+ getDescription() {
32
+ return 'set the single (target) snapshot of control run';
33
+ }
34
+ parse(config, args) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ let dirs = null;
37
+ const optionName = this.getOptionName();
38
+ if (optionName in args) {
39
+ const snapshotFile = (0, ExperimentOptionsUtils_1.validateHeapSnapshotFileOrThrow)(args[optionName]);
40
+ dirs = [(0, ExperimentOptionsUtils_1.createTransientWorkDirFromSingleHeapSnapshot)(snapshotFile)];
41
+ }
42
+ if (config.verbose && dirs && dirs[0]) {
43
+ core_1.info.lowLevel(`creating control working directory: ${dirs[0]}`);
44
+ }
45
+ return { controlWorkDirs: dirs };
46
+ });
47
+ }
48
+ }
49
+ exports.default = SetControlWorkDirOption;
@@ -0,0 +1,20 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { MemLabConfig, Nullable } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class SetTreatmentWorkDirOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<{
17
+ treatmentWorkDirs?: Nullable<string[]>;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=SetTreatmentSnapshotOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SetTreatmentSnapshotOption.d.ts","sourceRoot":"","sources":["../../../src/options/experiment/SetTreatmentSnapshotOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAC,UAAU,EAAO,MAAM,cAAc,CAAC;AAO9C,MAAM,CAAC,OAAO,OAAO,yBAA0B,SAAQ,UAAU;IAC/D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIlB,KAAK,CACT,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;QAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;KAAC,CAAC;CAYrD"}
@@ -0,0 +1,49 @@
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
+ * @format
9
+ * @oncall web_perf_infra
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ const ExperimentOptionsUtils_1 = require("./utils/ExperimentOptionsUtils");
27
+ class SetTreatmentWorkDirOption extends core_1.BaseOption {
28
+ getOptionName() {
29
+ return OptionConstant_1.default.optionNames.TREATMENT_SNAPSHOT;
30
+ }
31
+ getDescription() {
32
+ return 'set the single (target) snapshot of treatment run';
33
+ }
34
+ parse(config, args) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ let dirs = null;
37
+ const optionName = this.getOptionName();
38
+ if (optionName in args) {
39
+ const snapshotFile = (0, ExperimentOptionsUtils_1.validateHeapSnapshotFileOrThrow)(args[optionName]);
40
+ dirs = [(0, ExperimentOptionsUtils_1.createTransientWorkDirFromSingleHeapSnapshot)(snapshotFile)];
41
+ }
42
+ if (config.verbose && dirs && dirs[0]) {
43
+ core_1.info.lowLevel(`creating treatment working directory: ${dirs[0]}`);
44
+ }
45
+ return { treatmentWorkDirs: dirs };
46
+ });
47
+ }
48
+ }
49
+ exports.default = SetTreatmentWorkDirOption;
@@ -0,0 +1,13 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import { AnyValue } from '@memlab/core';
11
+ export declare function validateHeapSnapshotFileOrThrow(file: AnyValue): string;
12
+ export declare function createTransientWorkDirFromSingleHeapSnapshot(file: string): string;
13
+ //# sourceMappingURL=ExperimentOptionsUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExperimentOptionsUtils.d.ts","sourceRoot":"","sources":["../../../../src/options/experiment/utils/ExperimentOptionsUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAC,QAAQ,EAAmC,MAAM,cAAc,CAAC;AAGxE,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAetE;AAED,wBAAgB,4CAA4C,CAC1D,IAAI,EAAE,MAAM,GACX,MAAM,CAIR"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTransientWorkDirFromSingleHeapSnapshot = exports.validateHeapSnapshotFileOrThrow = void 0;
4
+ /**
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ *
10
+ * @format
11
+ * @oncall web_perf_infra
12
+ */
13
+ const core_1 = require("@memlab/core");
14
+ const fs_extra_1 = require("fs-extra");
15
+ function validateHeapSnapshotFileOrThrow(file) {
16
+ if (typeof file !== 'string') {
17
+ throw core_1.utils.haltOrThrow(`Heap snapshot file must be a string, but got ${typeof file}`);
18
+ }
19
+ if (!file.endsWith('.heapsnapshot')) {
20
+ throw core_1.utils.haltOrThrow(`Heap snapshot file must end with .heapsnapshot, but got ${file}`);
21
+ }
22
+ if (!(0, fs_extra_1.existsSync)(file)) {
23
+ throw core_1.utils.haltOrThrow(`Heap snapshot file ${file} does not exist`);
24
+ }
25
+ return file;
26
+ }
27
+ exports.validateHeapSnapshotFileOrThrow = validateHeapSnapshotFileOrThrow;
28
+ function createTransientWorkDirFromSingleHeapSnapshot(file) {
29
+ const config = core_1.MemLabConfig.resetConfigWithTransientDir();
30
+ core_1.fileManager.createOrOverrideVisitOrderMetaFileForExternalSnapshot(file);
31
+ return config.workDir;
32
+ }
33
+ exports.createTransientWorkDirFromSingleHeapSnapshot = createTransientWorkDirFromSingleHeapSnapshot;
@@ -0,0 +1,20 @@
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
+ * @format
8
+ * @oncall web_perf_infra
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class HeapAnalysisPluginOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<{
17
+ workDir?: string;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=HeapAnalysisPluginOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeapAnalysisPluginOption.d.ts","sourceRoot":"","sources":["../../../src/options/heap/HeapAnalysisPluginOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,EAAY,YAAY,EAAC,MAAM,cAAc,CAAC;AACrD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAGxC,MAAM,CAAC,OAAO,OAAO,wBAAyB,SAAQ,UAAU;IAC9D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAOlB,KAAK,CACT,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC;CAS/B"}
@@ -0,0 +1,46 @@
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
+ * @format
9
+ * @oncall web_perf_infra
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ class HeapAnalysisPluginOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return OptionConstant_1.default.optionNames.HEAP_ANALYSIS_PLUGIN_FILE;
29
+ }
30
+ getDescription() {
31
+ return ('specify the external heap analysis plugin file ' +
32
+ '(must be a vanilla JS file ended with `Analysis.js` suffix)');
33
+ }
34
+ parse(config, args) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ const name = this.getOptionName();
37
+ const ret = {};
38
+ const heapAnalysisPlugin = args[name];
39
+ if (heapAnalysisPlugin) {
40
+ ret.heapAnalysisPlugin = heapAnalysisPlugin;
41
+ }
42
+ return ret;
43
+ });
44
+ }
45
+ }
46
+ exports.default = HeapAnalysisPluginOption;
@@ -13,8 +13,10 @@ declare const optionConstants: {
13
13
  BASELINE: string;
14
14
  CLEAN_UP_SNAPSHOT: string;
15
15
  CONTINUS_TEST: string;
16
+ CONTROL_SNAPSHOT: string;
16
17
  CONTROL_WORK_DIR: string;
17
18
  CHROMIUM_BINARY: string;
19
+ CHROMIUM_PROTOCOL_TIMEOUT: string;
18
20
  DEVICE: string;
19
21
  DISABLE_WEB_SECURITY: string;
20
22
  DISABLE_XVFB: string;
@@ -22,6 +24,7 @@ declare const optionConstants: {
22
24
  FINAL: string;
23
25
  FULL: string;
24
26
  HEADFUL: string;
27
+ HEAP_ANALYSIS_PLUGIN_FILE: string;
25
28
  HELP: string;
26
29
  IGNORE_LEAK_CLUSTER_SIZE_BELOW: string;
27
30
  INTERACTION: string;
@@ -53,6 +56,7 @@ declare const optionConstants: {
53
56
  TRACE_ALL_OBJECTS: string;
54
57
  TRACE_CONTAINS: string;
55
58
  TRACE_OBJECT_SIZE_ABOVE: string;
59
+ TREATMENT_SNAPSHOT: string;
56
60
  TREATMENT_WORK_DIR: string;
57
61
  USER_AGENT: string;
58
62
  VERBOSE: string;
@@ -73,8 +77,10 @@ declare const _default: {
73
77
  BASELINE: string;
74
78
  CLEAN_UP_SNAPSHOT: string;
75
79
  CONTINUS_TEST: string;
80
+ CONTROL_SNAPSHOT: string;
76
81
  CONTROL_WORK_DIR: string;
77
82
  CHROMIUM_BINARY: string;
83
+ CHROMIUM_PROTOCOL_TIMEOUT: string;
78
84
  DEVICE: string;
79
85
  DISABLE_WEB_SECURITY: string;
80
86
  DISABLE_XVFB: string;
@@ -82,6 +88,7 @@ declare const _default: {
82
88
  FINAL: string;
83
89
  FULL: string;
84
90
  HEADFUL: string;
91
+ HEAP_ANALYSIS_PLUGIN_FILE: string;
85
92
  HELP: string;
86
93
  IGNORE_LEAK_CLUSTER_SIZE_BELOW: string;
87
94
  INTERACTION: string;
@@ -113,6 +120,7 @@ declare const _default: {
113
120
  TRACE_ALL_OBJECTS: string;
114
121
  TRACE_CONTAINS: string;
115
122
  TRACE_OBJECT_SIZE_ABOVE: string;
123
+ TREATMENT_SNAPSHOT: string;
116
124
  TREATMENT_WORK_DIR: string;
117
125
  USER_AGENT: string;
118
126
  VERBOSE: string;
@@ -1 +1 @@
1
- {"version":3,"file":"OptionConstant.d.ts","sourceRoot":"","sources":["../../../src/options/lib/OptionConstant.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+DH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGpB,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACrD,wBAIE"}
1
+ {"version":3,"file":"OptionConstant.d.ts","sourceRoot":"","sources":["../../../src/options/lib/OptionConstant.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmEH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGpB,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACrD,wBAIE"}
@@ -15,8 +15,10 @@ const optionNames = {
15
15
  BASELINE: 'baseline',
16
16
  CLEAN_UP_SNAPSHOT: 'clean-up-snapshot',
17
17
  CONTINUS_TEST: 'ContinuousTest',
18
+ CONTROL_SNAPSHOT: 'control-snapshot',
18
19
  CONTROL_WORK_DIR: 'control-work-dir',
19
20
  CHROMIUM_BINARY: 'chromium-binary',
21
+ CHROMIUM_PROTOCOL_TIMEOUT: 'protocol-timeout',
20
22
  DEVICE: 'device',
21
23
  DISABLE_WEB_SECURITY: 'disable-web-security',
22
24
  DISABLE_XVFB: 'disable-xvfb',
@@ -24,6 +26,7 @@ const optionNames = {
24
26
  FINAL: 'final',
25
27
  FULL: 'full',
26
28
  HEADFUL: 'headful',
29
+ HEAP_ANALYSIS_PLUGIN_FILE: 'analysis-plugin',
27
30
  HELP: 'help',
28
31
  IGNORE_LEAK_CLUSTER_SIZE_BELOW: 'ignore-leak-cluster-size-below',
29
32
  INTERACTION: 'interaction',
@@ -55,6 +58,7 @@ const optionNames = {
55
58
  TRACE_ALL_OBJECTS: 'trace-all-objects',
56
59
  TRACE_CONTAINS: 'trace-contains',
57
60
  TRACE_OBJECT_SIZE_ABOVE: 'trace-object-size-above',
61
+ TREATMENT_SNAPSHOT: 'treatment-snapshot',
58
62
  TREATMENT_WORK_DIR: 'treatment-work-dir',
59
63
  USER_AGENT: 'user-agent',
60
64
  VERBOSE: 'verbose',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memlab/cli",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "license": "MIT",
5
5
  "description": "command line interface for memlab",
6
6
  "author": "Liang Gong <lgong@fb.com>",
@@ -26,10 +26,10 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@memlab/api": "^1.0.11",
30
- "@memlab/core": "^1.1.13",
31
- "@memlab/e2e": "^1.0.11",
32
- "@memlab/heap-analysis": "^1.0.7",
29
+ "@memlab/api": "^1.0.27",
30
+ "@memlab/core": "^1.1.28",
31
+ "@memlab/e2e": "^1.0.28",
32
+ "@memlab/heap-analysis": "^1.0.25",
33
33
  "ansi": "^0.3.1",
34
34
  "babar": "^0.2.0",
35
35
  "blessed": "^0.1.81",