modestbench 0.2.0 → 0.3.1
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/CHANGELOG.md +27 -0
- package/README.md +131 -34
- package/dist/cli/commands/analyze.cjs +60 -0
- package/dist/cli/commands/analyze.cjs.map +1 -0
- package/dist/cli/commands/analyze.d.cts +35 -0
- package/dist/cli/commands/analyze.d.cts.map +1 -0
- package/dist/cli/commands/analyze.d.ts +35 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +56 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/baseline.cjs +404 -0
- package/dist/cli/commands/baseline.cjs.map +1 -0
- package/dist/cli/commands/baseline.d.cts +72 -0
- package/dist/cli/commands/baseline.d.cts.map +1 -0
- package/dist/cli/commands/baseline.d.ts +72 -0
- package/dist/cli/commands/baseline.d.ts.map +1 -0
- package/dist/cli/commands/baseline.js +396 -0
- package/dist/cli/commands/baseline.js.map +1 -0
- package/dist/cli/commands/history.d.cts +1 -1
- package/dist/cli/commands/history.d.cts.map +1 -1
- package/dist/cli/commands/history.d.ts +1 -1
- package/dist/cli/commands/history.d.ts.map +1 -1
- package/dist/cli/commands/init.cjs +99 -166
- package/dist/cli/commands/init.cjs.map +1 -1
- package/dist/cli/commands/init.d.cts +4 -4
- package/dist/cli/commands/init.d.cts.map +1 -1
- package/dist/cli/commands/init.d.ts +4 -4
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +99 -166
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/run.cjs +146 -127
- package/dist/cli/commands/run.cjs.map +1 -1
- package/dist/cli/commands/run.d.cts +16 -3
- package/dist/cli/commands/run.d.cts.map +1 -1
- package/dist/cli/commands/run.d.ts +16 -3
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +145 -93
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.cjs +583 -394
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +4 -16
- package/dist/cli/index.d.cts.map +1 -1
- package/dist/cli/index.d.ts +4 -16
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +575 -386
- package/dist/cli/index.js.map +1 -1
- package/dist/config/budget-schema.cjs +172 -0
- package/dist/config/budget-schema.cjs.map +1 -0
- package/dist/config/budget-schema.d.cts +59 -0
- package/dist/config/budget-schema.d.cts.map +1 -0
- package/dist/config/budget-schema.d.ts +59 -0
- package/dist/config/budget-schema.d.ts.map +1 -0
- package/dist/config/budget-schema.js +166 -0
- package/dist/config/budget-schema.js.map +1 -0
- package/dist/config/schema.cjs +182 -2
- package/dist/config/schema.cjs.map +1 -1
- package/dist/config/schema.d.cts +122 -3
- package/dist/config/schema.d.cts.map +1 -1
- package/dist/config/schema.d.ts +122 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +180 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/constants.cjs +45 -2
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +41 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +41 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +44 -1
- package/dist/constants.js.map +1 -1
- package/dist/core/engine.cjs +114 -23
- package/dist/core/engine.cjs.map +1 -1
- package/dist/core/engine.d.cts +7 -7
- package/dist/core/engine.d.cts.map +1 -1
- package/dist/core/engine.d.ts +7 -7
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +115 -24
- package/dist/core/engine.js.map +1 -1
- package/dist/core/engines/accurate-engine.cjs +171 -36
- package/dist/core/engines/accurate-engine.cjs.map +1 -1
- package/dist/core/engines/accurate-engine.d.cts +5 -0
- package/dist/core/engines/accurate-engine.d.cts.map +1 -1
- package/dist/core/engines/accurate-engine.d.ts +5 -0
- package/dist/core/engines/accurate-engine.d.ts.map +1 -1
- package/dist/core/engines/accurate-engine.js +171 -36
- package/dist/core/engines/accurate-engine.js.map +1 -1
- package/dist/core/engines/tinybench-engine.cjs +3 -2
- package/dist/core/engines/tinybench-engine.cjs.map +1 -1
- package/dist/core/engines/tinybench-engine.d.cts.map +1 -1
- package/dist/core/engines/tinybench-engine.d.ts.map +1 -1
- package/dist/core/engines/tinybench-engine.js +3 -2
- package/dist/core/engines/tinybench-engine.js.map +1 -1
- package/dist/core/output-path-resolver.cjs +8 -1
- package/dist/core/output-path-resolver.cjs.map +1 -1
- package/dist/core/output-path-resolver.d.cts.map +1 -1
- package/dist/core/output-path-resolver.d.ts.map +1 -1
- package/dist/core/output-path-resolver.js +9 -2
- package/dist/core/output-path-resolver.js.map +1 -1
- package/dist/errors/base.cjs +12 -3
- package/dist/errors/base.cjs.map +1 -1
- package/dist/errors/base.d.cts +7 -0
- package/dist/errors/base.d.cts.map +1 -1
- package/dist/errors/base.d.ts +7 -0
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/base.js +10 -2
- package/dist/errors/base.js.map +1 -1
- package/dist/errors/budget.cjs +37 -0
- package/dist/errors/budget.cjs.map +1 -0
- package/dist/errors/budget.d.cts +31 -0
- package/dist/errors/budget.d.cts.map +1 -0
- package/dist/errors/budget.d.ts +31 -0
- package/dist/errors/budget.d.ts.map +1 -0
- package/dist/errors/budget.js +33 -0
- package/dist/errors/budget.js.map +1 -0
- package/dist/errors/index.cjs +4 -1
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +1 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/index.cjs +13 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/reporters/csv.cjs +37 -17
- package/dist/reporters/csv.cjs.map +1 -1
- package/dist/reporters/csv.d.cts +3 -6
- package/dist/reporters/csv.d.cts.map +1 -1
- package/dist/reporters/csv.d.ts +3 -6
- package/dist/reporters/csv.d.ts.map +1 -1
- package/dist/reporters/csv.js +37 -17
- package/dist/reporters/csv.js.map +1 -1
- package/dist/reporters/human.cjs +290 -67
- package/dist/reporters/human.cjs.map +1 -1
- package/dist/reporters/human.d.cts +25 -13
- package/dist/reporters/human.d.cts.map +1 -1
- package/dist/reporters/human.d.ts +25 -13
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +290 -67
- package/dist/reporters/human.js.map +1 -1
- package/dist/reporters/json.cjs +23 -48
- package/dist/reporters/json.cjs.map +1 -1
- package/dist/reporters/json.d.cts +2 -28
- package/dist/reporters/json.d.cts.map +1 -1
- package/dist/reporters/json.d.ts +2 -28
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +25 -50
- package/dist/reporters/json.js.map +1 -1
- package/dist/reporters/profile-human.cjs +154 -0
- package/dist/reporters/profile-human.cjs.map +1 -0
- package/dist/reporters/profile-human.d.cts +44 -0
- package/dist/reporters/profile-human.d.cts.map +1 -0
- package/dist/reporters/profile-human.d.ts +44 -0
- package/dist/reporters/profile-human.d.ts.map +1 -0
- package/dist/reporters/profile-human.js +147 -0
- package/dist/reporters/profile-human.js.map +1 -0
- package/dist/reporters/simple.cjs +67 -45
- package/dist/reporters/simple.cjs.map +1 -1
- package/dist/reporters/simple.d.cts +14 -14
- package/dist/reporters/simple.d.cts.map +1 -1
- package/dist/reporters/simple.d.ts +14 -14
- package/dist/reporters/simple.d.ts.map +1 -1
- package/dist/reporters/simple.js +67 -45
- package/dist/reporters/simple.js.map +1 -1
- package/dist/schema/modestbench-config.schema.json +153 -0
- package/dist/services/baseline-storage.cjs +151 -0
- package/dist/services/baseline-storage.cjs.map +1 -0
- package/dist/services/baseline-storage.d.cts +55 -0
- package/dist/services/baseline-storage.d.cts.map +1 -0
- package/dist/services/baseline-storage.d.ts +55 -0
- package/dist/services/baseline-storage.d.ts.map +1 -0
- package/dist/services/baseline-storage.js +147 -0
- package/dist/services/baseline-storage.js.map +1 -0
- package/dist/services/budget-evaluator.cjs +146 -0
- package/dist/services/budget-evaluator.cjs.map +1 -0
- package/dist/services/budget-evaluator.d.cts +29 -0
- package/dist/services/budget-evaluator.d.cts.map +1 -0
- package/dist/services/budget-evaluator.d.ts +29 -0
- package/dist/services/budget-evaluator.d.ts.map +1 -0
- package/dist/services/budget-evaluator.js +142 -0
- package/dist/services/budget-evaluator.js.map +1 -0
- package/dist/services/config-manager.cjs +24 -10
- package/dist/services/config-manager.cjs.map +1 -1
- package/dist/services/config-manager.d.cts +6 -1
- package/dist/services/config-manager.d.cts.map +1 -1
- package/dist/services/config-manager.d.ts +6 -1
- package/dist/services/config-manager.d.ts.map +1 -1
- package/dist/services/config-manager.js +24 -10
- package/dist/services/config-manager.js.map +1 -1
- package/dist/services/file-loader.cjs +3 -6
- package/dist/services/file-loader.cjs.map +1 -1
- package/dist/services/file-loader.d.cts.map +1 -1
- package/dist/services/file-loader.d.ts.map +1 -1
- package/dist/services/file-loader.js +3 -6
- package/dist/services/file-loader.js.map +1 -1
- package/dist/services/profiler/profile-filter.cjs +116 -0
- package/dist/services/profiler/profile-filter.cjs.map +1 -0
- package/dist/services/profiler/profile-filter.d.cts +20 -0
- package/dist/services/profiler/profile-filter.d.cts.map +1 -0
- package/dist/services/profiler/profile-filter.d.ts +20 -0
- package/dist/services/profiler/profile-filter.d.ts.map +1 -0
- package/dist/services/profiler/profile-filter.js +112 -0
- package/dist/services/profiler/profile-filter.js.map +1 -0
- package/dist/services/profiler/profile-parser.cjs +139 -0
- package/dist/services/profiler/profile-parser.cjs.map +1 -0
- package/dist/services/profiler/profile-parser.d.cts +18 -0
- package/dist/services/profiler/profile-parser.d.cts.map +1 -0
- package/dist/services/profiler/profile-parser.d.ts +18 -0
- package/dist/services/profiler/profile-parser.d.ts.map +1 -0
- package/dist/services/profiler/profile-parser.js +132 -0
- package/dist/services/profiler/profile-parser.js.map +1 -0
- package/dist/services/profiler/profile-runner.cjs +90 -0
- package/dist/services/profiler/profile-runner.cjs.map +1 -0
- package/dist/services/profiler/profile-runner.d.cts +29 -0
- package/dist/services/profiler/profile-runner.d.cts.map +1 -0
- package/dist/services/profiler/profile-runner.d.ts +29 -0
- package/dist/services/profiler/profile-runner.d.ts.map +1 -0
- package/dist/services/profiler/profile-runner.js +86 -0
- package/dist/services/profiler/profile-runner.js.map +1 -0
- package/dist/services/progress-manager.cjs +10 -2
- package/dist/services/progress-manager.cjs.map +1 -1
- package/dist/services/progress-manager.d.cts +2 -0
- package/dist/services/progress-manager.d.cts.map +1 -1
- package/dist/services/progress-manager.d.ts +2 -0
- package/dist/services/progress-manager.d.ts.map +1 -1
- package/dist/services/progress-manager.js +10 -2
- package/dist/services/progress-manager.js.map +1 -1
- package/dist/services/reporter-registry.cjs +18 -24
- package/dist/services/reporter-registry.cjs.map +1 -1
- package/dist/services/reporter-registry.d.cts +18 -40
- package/dist/services/reporter-registry.d.cts.map +1 -1
- package/dist/services/reporter-registry.d.ts +18 -40
- package/dist/services/reporter-registry.d.ts.map +1 -1
- package/dist/services/reporter-registry.js +18 -24
- package/dist/services/reporter-registry.js.map +1 -1
- package/dist/types/budgets.cjs +8 -0
- package/dist/types/budgets.cjs.map +1 -0
- package/dist/types/budgets.d.cts +149 -0
- package/dist/types/budgets.d.cts.map +1 -0
- package/dist/types/budgets.d.ts +149 -0
- package/dist/types/budgets.d.ts.map +1 -0
- package/dist/types/budgets.js +7 -0
- package/dist/types/budgets.js.map +1 -0
- package/dist/types/cli.cjs +2 -11
- package/dist/types/cli.cjs.map +1 -1
- package/dist/types/cli.d.cts +3 -227
- package/dist/types/cli.d.cts.map +1 -1
- package/dist/types/cli.d.ts +3 -227
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/cli.js +2 -11
- package/dist/types/cli.js.map +1 -1
- package/dist/types/core.cjs +6 -1
- package/dist/types/core.cjs.map +1 -1
- package/dist/types/core.d.cts +15 -2
- package/dist/types/core.d.cts.map +1 -1
- package/dist/types/core.d.ts +15 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js +2 -1
- package/dist/types/core.js.map +1 -1
- package/dist/types/index.cjs +5 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +2 -0
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/interfaces.d.cts +19 -8
- package/dist/types/interfaces.d.cts.map +1 -1
- package/dist/types/interfaces.d.ts +19 -8
- package/dist/types/interfaces.d.ts.map +1 -1
- package/dist/types/profiler.cjs +11 -0
- package/dist/types/profiler.cjs.map +1 -0
- package/dist/types/profiler.d.cts +102 -0
- package/dist/types/profiler.d.cts.map +1 -0
- package/dist/types/profiler.d.ts +102 -0
- package/dist/types/profiler.d.ts.map +1 -0
- package/dist/types/profiler.js +10 -0
- package/dist/types/profiler.js.map +1 -0
- package/dist/types/utility.cjs.map +1 -1
- package/dist/types/utility.d.cts +0 -8
- package/dist/types/utility.d.cts.map +1 -1
- package/dist/types/utility.d.ts +0 -8
- package/dist/types/utility.d.ts.map +1 -1
- package/dist/types/utility.js.map +1 -1
- package/dist/utils/identifiers.cjs +32 -0
- package/dist/utils/identifiers.cjs.map +1 -0
- package/dist/utils/identifiers.d.cts +32 -0
- package/dist/utils/identifiers.d.cts.map +1 -0
- package/dist/utils/identifiers.d.ts +32 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/identifiers.js +27 -0
- package/dist/utils/identifiers.js.map +1 -0
- package/dist/utils/package.cjs +40 -0
- package/dist/utils/package.cjs.map +1 -0
- package/dist/utils/package.d.cts +15 -0
- package/dist/utils/package.d.cts.map +1 -0
- package/dist/utils/package.d.ts +15 -0
- package/dist/utils/package.d.ts.map +1 -0
- package/dist/utils/package.js +33 -0
- package/dist/utils/package.js.map +1 -0
- package/dist/utils/type-guards.cjs +48 -0
- package/dist/utils/type-guards.cjs.map +1 -0
- package/dist/utils/type-guards.d.cts +22 -0
- package/dist/utils/type-guards.d.cts.map +1 -0
- package/dist/utils/type-guards.d.ts +22 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +43 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/package.json +18 -19
- package/src/cli/commands/analyze.ts +101 -0
- package/src/cli/commands/baseline.ts +577 -0
- package/src/cli/commands/history.ts +1 -1
- package/src/cli/commands/init.ts +116 -194
- package/src/cli/commands/run.ts +183 -113
- package/src/cli/index.ts +425 -183
- package/src/config/budget-schema.ts +189 -0
- package/src/config/schema.ts +260 -1
- package/src/constants.ts +53 -1
- package/src/core/engine.ts +169 -22
- package/src/core/engines/accurate-engine.ts +195 -44
- package/src/core/engines/tinybench-engine.ts +3 -2
- package/src/core/output-path-resolver.ts +10 -2
- package/src/errors/base.ts +11 -2
- package/src/errors/budget.ts +38 -0
- package/src/errors/index.ts +3 -0
- package/src/index.ts +9 -0
- package/src/reporters/csv.ts +54 -25
- package/src/reporters/human.ts +434 -115
- package/src/reporters/json.ts +26 -71
- package/src/reporters/profile-human.ts +210 -0
- package/src/reporters/simple.ts +88 -54
- package/src/services/baseline-storage.ts +199 -0
- package/src/services/budget-evaluator.ts +182 -0
- package/src/services/config-manager.ts +24 -9
- package/src/services/file-loader.ts +3 -6
- package/src/services/profiler/profile-filter.ts +147 -0
- package/src/services/profiler/profile-parser.ts +194 -0
- package/src/services/profiler/profile-runner.ts +121 -0
- package/src/services/progress-manager.ts +12 -2
- package/src/services/reporter-registry.ts +46 -81
- package/src/types/budgets.ts +180 -0
- package/src/types/cli.ts +5 -238
- package/src/types/core.ts +52 -10
- package/src/types/index.ts +5 -0
- package/src/types/interfaces.ts +24 -6
- package/src/types/profiler.ts +135 -0
- package/src/types/utility.ts +0 -10
- package/src/utils/identifiers.ts +58 -0
- package/src/utils/package.ts +35 -0
- package/src/utils/type-guards.ts +51 -0
package/src/core/engine.ts
CHANGED
|
@@ -7,13 +7,17 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { randomBytes } from 'node:crypto';
|
|
10
|
+
import { relative as pathRelative } from 'node:path';
|
|
10
11
|
|
|
11
12
|
import type {
|
|
13
|
+
BaselineSummaryData,
|
|
12
14
|
BenchmarkDefinition,
|
|
13
15
|
BenchmarkEngine,
|
|
14
16
|
BenchmarkRun,
|
|
15
17
|
BenchmarkSuite,
|
|
16
18
|
BenchmarkTask,
|
|
19
|
+
Budget,
|
|
20
|
+
BudgetSummary,
|
|
17
21
|
CiInfo,
|
|
18
22
|
ConfigurationManager,
|
|
19
23
|
EnvironmentInfo,
|
|
@@ -26,7 +30,9 @@ import type {
|
|
|
26
30
|
Reporter,
|
|
27
31
|
ReporterRegistry,
|
|
28
32
|
RunConfiguration,
|
|
33
|
+
RunId,
|
|
29
34
|
SuiteResult,
|
|
35
|
+
TaskId,
|
|
30
36
|
TaskResult,
|
|
31
37
|
ValidationError,
|
|
32
38
|
ValidationResult,
|
|
@@ -35,11 +41,15 @@ import type {
|
|
|
35
41
|
|
|
36
42
|
import {
|
|
37
43
|
BenchmarkExecutionError,
|
|
44
|
+
BudgetExceededError,
|
|
38
45
|
FileDiscoveryError,
|
|
39
46
|
SchemaValidationError,
|
|
40
47
|
SetupError,
|
|
41
48
|
StructureValidationError,
|
|
42
49
|
} from '../errors/index.js';
|
|
50
|
+
import { BaselineStorageService } from '../services/baseline-storage.js';
|
|
51
|
+
import { BudgetEvaluator } from '../services/budget-evaluator.js';
|
|
52
|
+
import { createRunId, createTaskId } from '../types/index.js';
|
|
43
53
|
|
|
44
54
|
/**
|
|
45
55
|
* Dependencies required by the BenchmarkEngine
|
|
@@ -78,6 +88,20 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
78
88
|
this.progressManager = dependencies.progressManager;
|
|
79
89
|
}
|
|
80
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Generate a unique run ID
|
|
93
|
+
*
|
|
94
|
+
* Uses crypto.randomBytes for cryptographically random 7-character IDs.
|
|
95
|
+
* Format: 7 lowercase alphanumeric characters (e.g., "k3m9x2p")
|
|
96
|
+
*/
|
|
97
|
+
private static generateRunId(this: void): RunId {
|
|
98
|
+
// Generate random bytes, convert to hex, then to base36, take first 7 chars
|
|
99
|
+
const hex = randomBytes(4).toString('hex');
|
|
100
|
+
const num = parseInt(hex, 16);
|
|
101
|
+
const id = num.toString(36).padStart(7, '0').substring(0, 7);
|
|
102
|
+
return createRunId(id);
|
|
103
|
+
}
|
|
104
|
+
|
|
81
105
|
/**
|
|
82
106
|
* Discover benchmark files matching the pattern(s)
|
|
83
107
|
*/
|
|
@@ -136,7 +160,7 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
136
160
|
}
|
|
137
161
|
|
|
138
162
|
// 4. Initialize progress tracking
|
|
139
|
-
const runId =
|
|
163
|
+
const runId = ModestBenchEngine.generateRunId();
|
|
140
164
|
|
|
141
165
|
// Pre-calculate total tasks for progress tracking
|
|
142
166
|
let totalTasks = 0;
|
|
@@ -212,9 +236,9 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
212
236
|
|
|
213
237
|
// Register progress callbacks with reporters that support them
|
|
214
238
|
for (const reporter of reporters) {
|
|
215
|
-
if (
|
|
239
|
+
if (reporter.onProgress) {
|
|
216
240
|
this.progressManager.onProgress((state) => {
|
|
217
|
-
void reporter.onProgress(state);
|
|
241
|
+
void reporter.onProgress?.(state);
|
|
218
242
|
});
|
|
219
243
|
}
|
|
220
244
|
}
|
|
@@ -227,12 +251,17 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
227
251
|
|
|
228
252
|
for (const filePath of files) {
|
|
229
253
|
try {
|
|
230
|
-
//
|
|
231
|
-
|
|
254
|
+
// Normalize file path to be relative to cwd
|
|
255
|
+
const cwd = config.cwd || process.cwd();
|
|
256
|
+
const relativePath = pathRelative(cwd, filePath);
|
|
257
|
+
|
|
258
|
+
// Call reporter onFileStart with relative path
|
|
259
|
+
await this.callReporters(reporters, 'onFileStart', relativePath);
|
|
232
260
|
|
|
233
261
|
const fileResult = await this.executeBenchmarkFile(
|
|
234
262
|
filePath,
|
|
235
263
|
mergedConfig,
|
|
264
|
+
cwd,
|
|
236
265
|
reporters,
|
|
237
266
|
signal,
|
|
238
267
|
);
|
|
@@ -246,6 +275,16 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
246
275
|
currentFile: filePath,
|
|
247
276
|
filesCompleted: fileResults.length,
|
|
248
277
|
});
|
|
278
|
+
|
|
279
|
+
// Check for bail: stop execution if any task failed
|
|
280
|
+
if (mergedConfig.bail) {
|
|
281
|
+
const hasFailedTask = fileResult.suites.some((suite) =>
|
|
282
|
+
suite.tasks.some((task) => task.error),
|
|
283
|
+
);
|
|
284
|
+
if (hasFailedTask) {
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
249
288
|
} catch (error) {
|
|
250
289
|
const fileError =
|
|
251
290
|
error instanceof Error ? error : new Error(String(error));
|
|
@@ -267,6 +306,11 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
267
306
|
|
|
268
307
|
// Call reporter onFileEnd for error case
|
|
269
308
|
await this.callReporters(reporters, 'onFileEnd', errorResult);
|
|
309
|
+
|
|
310
|
+
// Check bail flag for file-level errors
|
|
311
|
+
if (mergedConfig.bail) {
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
270
314
|
}
|
|
271
315
|
}
|
|
272
316
|
|
|
@@ -302,10 +346,103 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
302
346
|
}
|
|
303
347
|
|
|
304
348
|
const overallMean = totalOperations > 0 ? totalTime / totalOperations : 0;
|
|
349
|
+
// Evaluate budgets if configured
|
|
350
|
+
let budgetSummary: BudgetSummary | undefined;
|
|
351
|
+
|
|
352
|
+
if (config.budgets && Object.keys(config.budgets).length > 0) {
|
|
353
|
+
const evaluator = new BudgetEvaluator();
|
|
354
|
+
const baselineStorage = new BaselineStorageService(process.cwd());
|
|
355
|
+
|
|
356
|
+
// Collect task results
|
|
357
|
+
const taskResults = new Map<TaskId, TaskResult>();
|
|
358
|
+
|
|
359
|
+
for (const file of fileResults) {
|
|
360
|
+
for (const suite of file.suites) {
|
|
361
|
+
for (const task of suite.tasks) {
|
|
362
|
+
if (!task.error) {
|
|
363
|
+
// file.filePath is already relative to cwd
|
|
364
|
+
const taskId = createTaskId(
|
|
365
|
+
file.filePath,
|
|
366
|
+
suite.name,
|
|
367
|
+
task.name,
|
|
368
|
+
);
|
|
369
|
+
taskResults.set(taskId, task);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Load baseline data if needed for relative budgets
|
|
376
|
+
let baselineData: Map<TaskId, BaselineSummaryData> | undefined;
|
|
377
|
+
|
|
378
|
+
// Check if any budgets use relative thresholds
|
|
379
|
+
const hasRelativeBudgets = Object.values(config.budgets).some(
|
|
380
|
+
(budget) => (budget as Budget).relative,
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
if (hasRelativeBudgets) {
|
|
384
|
+
const baselineName =
|
|
385
|
+
config.baseline || (await baselineStorage.getDefault());
|
|
386
|
+
|
|
387
|
+
if (baselineName) {
|
|
388
|
+
const baseline = await baselineStorage.getBaseline(baselineName);
|
|
389
|
+
|
|
390
|
+
if (baseline) {
|
|
391
|
+
// Cast keys to TaskId since they come from validated baseline storage
|
|
392
|
+
baselineData = new Map(
|
|
393
|
+
Object.entries(baseline.summary) as [
|
|
394
|
+
TaskId,
|
|
395
|
+
BaselineSummaryData,
|
|
396
|
+
][],
|
|
397
|
+
);
|
|
398
|
+
} else {
|
|
399
|
+
console.warn(
|
|
400
|
+
`Warning: Baseline "${baselineName}" not found. Relative budgets will be skipped.`,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
console.warn(
|
|
405
|
+
'Warning: Relative budgets configured but no baseline specified. Relative budgets will be skipped.',
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Evaluate budgets
|
|
411
|
+
budgetSummary = evaluator.evaluateRun(
|
|
412
|
+
config.budgets as Record<string, Budget>,
|
|
413
|
+
taskResults,
|
|
414
|
+
baselineData,
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
// Notify reporters of budget results
|
|
418
|
+
for (const reporter of reporters) {
|
|
419
|
+
if (reporter.onBudgetResult) {
|
|
420
|
+
await reporter.onBudgetResult(budgetSummary);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Handle budget failures based on budgetMode
|
|
425
|
+
if (budgetSummary.failed > 0) {
|
|
426
|
+
const mode = config.budgetMode || 'fail';
|
|
427
|
+
|
|
428
|
+
if (mode === 'fail') {
|
|
429
|
+
throw new BudgetExceededError(
|
|
430
|
+
`${budgetSummary.failed} of ${budgetSummary.total} budget(s) exceeded`,
|
|
431
|
+
budgetSummary,
|
|
432
|
+
);
|
|
433
|
+
} else if (mode === 'warn') {
|
|
434
|
+
console.warn(
|
|
435
|
+
`Warning: ${budgetSummary.failed} of ${budgetSummary.total} budget(s) exceeded`,
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
// mode === 'report': just include in output, don't fail
|
|
439
|
+
}
|
|
440
|
+
}
|
|
305
441
|
|
|
306
442
|
const endTime = new Date();
|
|
307
443
|
const finalRun: BenchmarkRun = {
|
|
308
444
|
...initialRun,
|
|
445
|
+
budgetSummary,
|
|
309
446
|
duration: endTime.getTime() - startTime.getTime(),
|
|
310
447
|
endTime,
|
|
311
448
|
files: fileResults,
|
|
@@ -489,6 +626,7 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
489
626
|
private async executeBenchmarkFile(
|
|
490
627
|
filePath: string,
|
|
491
628
|
config: ModestBenchConfig,
|
|
629
|
+
cwd: string,
|
|
492
630
|
reporters: Reporter[] = [],
|
|
493
631
|
signal?: AbortSignal,
|
|
494
632
|
): Promise<FileResult> {
|
|
@@ -514,7 +652,7 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
514
652
|
benchmarkDef.suites,
|
|
515
653
|
)) {
|
|
516
654
|
// Use shared filtering logic
|
|
517
|
-
const { anyTaskMatches, suiteMatches } =
|
|
655
|
+
const { anyTaskMatches, suiteMatches, tasksToRun } =
|
|
518
656
|
this.getFilteredTasksForSuite(
|
|
519
657
|
suiteData,
|
|
520
658
|
fileTags,
|
|
@@ -527,6 +665,15 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
527
665
|
continue;
|
|
528
666
|
}
|
|
529
667
|
|
|
668
|
+
// Emit suite init with task names for pre-calculation
|
|
669
|
+
const taskNames = tasksToRun.map(([name]) => name);
|
|
670
|
+
await this.callReporters(
|
|
671
|
+
reporters,
|
|
672
|
+
'onSuiteInit',
|
|
673
|
+
suiteName,
|
|
674
|
+
taskNames,
|
|
675
|
+
);
|
|
676
|
+
|
|
530
677
|
await this.callReporters(reporters, 'onSuiteStart', suiteName);
|
|
531
678
|
const suiteResult = await this.executeBenchmarkSuite(
|
|
532
679
|
suiteName,
|
|
@@ -543,11 +690,14 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
543
690
|
|
|
544
691
|
const endTime = new Date();
|
|
545
692
|
|
|
693
|
+
// Normalize file path to be relative to cwd
|
|
694
|
+
const relativePath = pathRelative(cwd, filePath);
|
|
695
|
+
|
|
546
696
|
return {
|
|
547
697
|
config: benchmarkDef.config,
|
|
548
698
|
duration: endTime.getTime() - startTime.getTime(),
|
|
549
699
|
endTime,
|
|
550
|
-
filePath,
|
|
700
|
+
filePath: relativePath,
|
|
551
701
|
startTime,
|
|
552
702
|
suites: suiteResults,
|
|
553
703
|
};
|
|
@@ -556,11 +706,14 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
556
706
|
const executionError =
|
|
557
707
|
error instanceof Error ? error : new Error(String(error));
|
|
558
708
|
|
|
709
|
+
// Normalize file path to be relative to cwd
|
|
710
|
+
const relativePath = pathRelative(cwd, filePath);
|
|
711
|
+
|
|
559
712
|
return {
|
|
560
713
|
duration: endTime.getTime() - startTime.getTime(),
|
|
561
714
|
endTime,
|
|
562
715
|
error: executionError,
|
|
563
|
-
filePath,
|
|
716
|
+
filePath: relativePath,
|
|
564
717
|
startTime,
|
|
565
718
|
suites: [],
|
|
566
719
|
};
|
|
@@ -624,6 +777,12 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
624
777
|
}
|
|
625
778
|
}
|
|
626
779
|
|
|
780
|
+
// Merge suite-level config with global config
|
|
781
|
+
// Suite-level config takes precedence over global config
|
|
782
|
+
const mergedConfig = suiteData.config
|
|
783
|
+
? { ...config, ...suiteData.config }
|
|
784
|
+
: config;
|
|
785
|
+
|
|
627
786
|
try {
|
|
628
787
|
// Process each task that passed filtering
|
|
629
788
|
for (const [taskName, taskData] of tasksToRun) {
|
|
@@ -632,13 +791,14 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
632
791
|
// Mark task as in-progress (shows as 0.5 progress for current task)
|
|
633
792
|
const currentState = this.progressManager.getState();
|
|
634
793
|
this.progressManager.update({
|
|
794
|
+
currentTask: taskName,
|
|
635
795
|
tasksCompleted: currentState.tasksCompleted + 0.5,
|
|
636
796
|
});
|
|
637
797
|
|
|
638
798
|
const taskResult = await this.executeBenchmarkTask(
|
|
639
799
|
taskName,
|
|
640
800
|
taskData,
|
|
641
|
-
|
|
801
|
+
mergedConfig,
|
|
642
802
|
reporters,
|
|
643
803
|
signal,
|
|
644
804
|
);
|
|
@@ -697,19 +857,6 @@ export abstract class ModestBenchEngine implements BenchmarkEngine {
|
|
|
697
857
|
}
|
|
698
858
|
}
|
|
699
859
|
|
|
700
|
-
/**
|
|
701
|
-
* Generate a unique run ID
|
|
702
|
-
*
|
|
703
|
-
* Uses crypto.randomBytes for cryptographically random 7-character IDs.
|
|
704
|
-
* Format: 7 lowercase alphanumeric characters (e.g., "k3m9x2p")
|
|
705
|
-
*/
|
|
706
|
-
private generateRunId(): string {
|
|
707
|
-
// Generate random bytes, convert to hex, then to base36, take first 7 chars
|
|
708
|
-
const hex = randomBytes(4).toString('hex');
|
|
709
|
-
const num = parseInt(hex, 16);
|
|
710
|
-
return num.toString(36).padStart(7, '0').substring(0, 7);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
860
|
/**
|
|
714
861
|
* Get CI/CD information if available
|
|
715
862
|
*/
|