Skip to content

Commit cbbc0cc

Browse files
CHANGE @W-20773111@ - Perf test for run rules (#400)
1 parent 5ae8756 commit cbbc0cc

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import {Engine, RuleDescription, Workspace} from "@salesforce/code-analyzer-engine-api";
2+
import {ESLintEnginePlugin} from "../src";
3+
import {DEFAULT_CONFIG, ESLintEngineConfig} from "../src/config";
4+
import {createDescribeOptions, createRunOptions} from "./test-helpers";
5+
6+
/**
7+
* One-off performance probe for running ESLint rules (runRules).
8+
*
9+
* What this test does:
10+
* - Instantiates the ESLint engine with the current base configuration.
11+
* - Discovers rules (describeRules), then selects a subset to run (e.g., Recommended).
12+
* - Runs the engine against the provided workspace (PERF_WS must be set).
13+
* - Samples Node's resident set size (RSS) and prints a JSON summary:
14+
* {
15+
* "files_scanned": <unique files that produced violations>,
16+
* "rules_run": <number of rules executed>,
17+
* "run_ms": <wall time in milliseconds for runRules>,
18+
* "peak_rss_mb": <approximate peak memory (MB) observed during the run>,
19+
* "violations": <total violations found>
20+
* }
21+
*
22+
* How to run (skipped by default; opt-in with env var):
23+
* ESLINT_ENGINE_PERF_RUN=true PERF_WS="/absolute/path/to/project" PERF_DISCOVER=true \
24+
* npm run test-typescript -- packages/code-analyzer-eslint-engine/test/perf-eslint-run.test.ts
25+
*
26+
* Optional env vars:
27+
* - PERF_RULES_LIMIT=200 → cap the number of rules to run (keeps runtime stable)
28+
* - PERF_DISCOVER=true → let ESLint auto-discover configs from PERF_WS (sets config_root to PERF_WS)
29+
* - You can toggle:
30+
* // disable_react_base_config: true,
31+
* // disable_typescript_base_config: true,
32+
* in the config below to attribute parser/plugin costs.
33+
*/
34+
const RUN = process.env.ESLINT_ENGINE_PERF_RUN === 'true';
35+
(RUN ? describe : describe.skip)('ESLint engine perf (runRules one-off)', () => {
36+
it('measures runRules wall time and peak RSS', async () => {
37+
const cfg: ESLintEngineConfig = {
38+
...DEFAULT_CONFIG,
39+
// Toggle to isolate costs if desired:
40+
disable_react_base_config: false,
41+
disable_typescript_base_config: true,
42+
config_root: __dirname,
43+
auto_discover_eslint_config: process.env.PERF_DISCOVER === 'true',
44+
};
45+
46+
const wsPath = process.env.PERF_WS;
47+
if (!wsPath) {
48+
throw new Error('PERF_WS env var must be set to an absolute path for runRules perf test.');
49+
}
50+
const ws: Workspace = new Workspace('perf', [wsPath]);
51+
if (process.env.PERF_DISCOVER === 'true') {
52+
cfg.config_root = wsPath;
53+
}
54+
55+
const engine: Engine = await new ESLintEnginePlugin().createEngine('eslint', cfg);
56+
57+
// Discover and select rules to run (Recommended by default), with an optional cap.
58+
const discovered: RuleDescription[] = await engine.describeRules(createDescribeOptions(ws));
59+
const rulesToRun: string[] = discovered
60+
.filter(r => r.tags.includes('Recommended'))
61+
.slice(0, Number(process.env.PERF_RULES_LIMIT) || 200)
62+
.map(r => r.name);
63+
64+
const peak = {rss: 0};
65+
const sampler = setInterval(() => {
66+
const m = process.memoryUsage();
67+
if (m.rss > peak.rss) peak.rss = m.rss;
68+
}, 50);
69+
70+
const mem0 = process.memoryUsage().rss;
71+
const t0 = performance.now();
72+
const results = await engine.runRules(rulesToRun, createRunOptions(ws));
73+
const t1 = performance.now();
74+
const mem1 = process.memoryUsage().rss;
75+
clearInterval(sampler);
76+
77+
// Calculate files that produced violations (as a proxy for scanned footprint).
78+
const filesScanned = Array.from(new Set(results.violations.map(v => v.codeLocations[0].file))).length;
79+
80+
// eslint-disable-next-line no-console
81+
console.log(JSON.stringify({
82+
files_scanned: filesScanned,
83+
rules_run: rulesToRun.length,
84+
run_ms: Math.round(t1 - t0),
85+
peak_rss_mb: Math.round(Math.max(peak.rss, mem0, mem1) / (1024 * 1024)),
86+
violations: results.violations.length
87+
}, null, 2));
88+
89+
expect(rulesToRun.length).toBeGreaterThan(0);
90+
});
91+
});
92+

0 commit comments

Comments
 (0)