blaze-performance-tester 3.2.2 → 3.2.4
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/dist/cli.js +3 -111
- package/dist/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -196,94 +196,6 @@ function loadBaselineData(filePath) {
|
|
|
196
196
|
}
|
|
197
197
|
return null;
|
|
198
198
|
}
|
|
199
|
-
async function generateScenarioTS(prompt) {
|
|
200
|
-
const apiKey = process.env.GEMINI_API_KEY;
|
|
201
|
-
if (!apiKey) {
|
|
202
|
-
throw new Error("\u274C Environment variable GEMINI_API_KEY is missing. AI scenario generation aborted.");
|
|
203
|
-
}
|
|
204
|
-
console.log("\u{1F9E0} Translating natural language requirements into TypeScript via Gemini 2.5 Flash...");
|
|
205
|
-
const systemInstruction = `
|
|
206
|
-
You are an expert Performance & Systems Reliability Engineer specializing in QuickJS-compatible virtual user load testing scripts for the Blaze framework.
|
|
207
|
-
Your task is to convert a natural language description into a clean, valid TypeScript simulation script.
|
|
208
|
-
|
|
209
|
-
The script must adhere to this exact structural import pattern:
|
|
210
|
-
\`\`\`typescript
|
|
211
|
-
import { VirtualUser } from '../src/core/vu';
|
|
212
|
-
|
|
213
|
-
export async function runScenario(vu: VirtualUser) {
|
|
214
|
-
// Setup headers
|
|
215
|
-
// Execute multi-step operations (e.g., fetching a login, parsing tokens, making subsequent requests)
|
|
216
|
-
// Manage dynamic value extraction (e.g., const token = response.json().token) and pass variables forward
|
|
217
|
-
// Include standard loops (e.g., for-loops) or timeouts as requested
|
|
218
|
-
}
|
|
219
|
-
\`\`\`
|
|
220
|
-
|
|
221
|
-
Rules:
|
|
222
|
-
1. Return ONLY executable, valid TypeScript script.
|
|
223
|
-
2. Cleanly extract dynamic payload fields or tokens and assign them to downstream headers.
|
|
224
|
-
3. Keep logic performance-optimized and sandbox-compatible.
|
|
225
|
-
4. Do NOT wrap code blocks in backticks like \`\`\`typescript. Start directly with the TypeScript imports and export block. Do not include markdown or text commentary.
|
|
226
|
-
`;
|
|
227
|
-
try {
|
|
228
|
-
const endpoint = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + apiKey;
|
|
229
|
-
const response = await fetch(endpoint, {
|
|
230
|
-
method: "POST",
|
|
231
|
-
headers: { "Content-Type": "application/json" },
|
|
232
|
-
body: JSON.stringify({
|
|
233
|
-
contents: [{ parts: [{ text: `Generate a Virtual User script for this scenario: ${prompt}` }] }],
|
|
234
|
-
generationConfig: {
|
|
235
|
-
temperature: 0.1,
|
|
236
|
-
maxOutputTokens: 65536
|
|
237
|
-
},
|
|
238
|
-
systemInstruction: {
|
|
239
|
-
parts: [{ text: systemInstruction }]
|
|
240
|
-
}
|
|
241
|
-
})
|
|
242
|
-
});
|
|
243
|
-
const data = await response.json();
|
|
244
|
-
if (data?.error) {
|
|
245
|
-
throw new Error(`Google API Error ${data.error.code}: ${data.error.message}`);
|
|
246
|
-
}
|
|
247
|
-
const candidateText = data?.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
248
|
-
if (!candidateText) {
|
|
249
|
-
throw new Error(`Malformed API layout or empty response body.`);
|
|
250
|
-
}
|
|
251
|
-
return candidateText.replace(/```typescript/g, "").replace(/```javascript/g, "").replace(/```/g, "").trim();
|
|
252
|
-
} catch (error) {
|
|
253
|
-
throw new Error(`Failed to generate script via Gemini: ${error.message || error}`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
async function handleScenarioGeneration(config) {
|
|
257
|
-
const targetDir = path.resolve(__dirname, "./tests");
|
|
258
|
-
const tsFilePath = path.join(targetDir, "generated_scenario.ts");
|
|
259
|
-
const jsFilePath = path.join(targetDir, "generated_scenario.js");
|
|
260
|
-
try {
|
|
261
|
-
if (!fs.existsSync(targetDir)) {
|
|
262
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
263
|
-
}
|
|
264
|
-
const tsCode = await generateScenarioTS(config.scenarioPrompt);
|
|
265
|
-
fs.writeFileSync(tsFilePath, tsCode, "utf-8");
|
|
266
|
-
console.log(`\u{1F4BE} Successfully generated scenario script saved to: ${tsFilePath}`);
|
|
267
|
-
console.log("\u2699\uFE0F Transpiling generated scenario to JavaScript for native QuickJS sandbox validation...");
|
|
268
|
-
let compiledSuccessfully = false;
|
|
269
|
-
try {
|
|
270
|
-
const { execSync } = require2("child_process");
|
|
271
|
-
execSync(`npx tsc "${tsFilePath}" --target es2020 --module commonjs --allowJs --skipLibCheck`, { stdio: "ignore" });
|
|
272
|
-
compiledSuccessfully = true;
|
|
273
|
-
} catch (e) {
|
|
274
|
-
console.warn("\u26A0\uFE0F TypeScript compiler (tsc) was not found or timed out. Falling back to clean JS copy conversion...");
|
|
275
|
-
}
|
|
276
|
-
if (!compiledSuccessfully) {
|
|
277
|
-
const cleanJs = tsCode.replace(/: VirtualUser/g, "").replace(/import {[^}]+} from .*/g, "").replace(/export async/g, "async");
|
|
278
|
-
fs.writeFileSync(jsFilePath, cleanJs, "utf-8");
|
|
279
|
-
}
|
|
280
|
-
console.log(`\u2705 Sandbox compilation resolved. Active test file: ${jsFilePath}`);
|
|
281
|
-
config.targetScript = jsFilePath;
|
|
282
|
-
} catch (error) {
|
|
283
|
-
console.error(`\u274C Scenario generation flow aborted: ${error.message || error}`);
|
|
284
|
-
process.exit(1);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
199
|
async function generateGeminiRCA(history, finalSummary, errorLogs) {
|
|
288
200
|
const apiKey = process.env.GEMINI_API_KEY;
|
|
289
201
|
if (!apiKey) {
|
|
@@ -320,8 +232,7 @@ Paragraph 3 - ARCHITECTURAL SIZING RECOMMENDATIONS: Give concrete, infrastructur
|
|
|
320
232
|
CRITICAL: Return ONLY plain paragraph text. Do not use markdown headers (###). If you use bold text, use standard HTML <strong> tags. Wrap lines cleanly.
|
|
321
233
|
`;
|
|
322
234
|
try {
|
|
323
|
-
const
|
|
324
|
-
const response = await fetch(endpoint, {
|
|
235
|
+
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${apiKey}`, {
|
|
325
236
|
method: "POST",
|
|
326
237
|
headers: { "Content-Type": "application/json" },
|
|
327
238
|
body: JSON.stringify({
|
|
@@ -389,9 +300,6 @@ async function main() {
|
|
|
389
300
|
return;
|
|
390
301
|
}
|
|
391
302
|
const config = parseArguments(args);
|
|
392
|
-
if (config.scenarioPrompt) {
|
|
393
|
-
await handleScenarioGeneration(config);
|
|
394
|
-
}
|
|
395
303
|
if (config.isCorrelate) {
|
|
396
304
|
await executeTestPipeline(config);
|
|
397
305
|
}
|
|
@@ -402,12 +310,6 @@ async function main() {
|
|
|
402
310
|
}
|
|
403
311
|
}
|
|
404
312
|
function parseArguments(args) {
|
|
405
|
-
const scenarioIdx = args.indexOf("--generate-scenario");
|
|
406
|
-
let scenarioPrompt = null;
|
|
407
|
-
if (scenarioIdx !== -1) {
|
|
408
|
-
scenarioPrompt = args[scenarioIdx + 1];
|
|
409
|
-
args.splice(scenarioIdx, 2);
|
|
410
|
-
}
|
|
411
313
|
const targetScript = path.resolve(args[0] || ".");
|
|
412
314
|
const isAgentic = args.includes("--agentic");
|
|
413
315
|
const isCorrelate = args.includes("--correlate");
|
|
@@ -461,7 +363,6 @@ function parseArguments(args) {
|
|
|
461
363
|
}
|
|
462
364
|
return {
|
|
463
365
|
targetScript,
|
|
464
|
-
scenarioPrompt,
|
|
465
366
|
isAgentic,
|
|
466
367
|
isCorrelate,
|
|
467
368
|
isSeo,
|
|
@@ -1062,11 +963,10 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
1062
963
|
`;
|
|
1063
964
|
}).join("");
|
|
1064
965
|
const gaugeColor = cards.healthScore >= 90 ? "#10b981" : cards.healthScore >= 70 ? "#f59e0b" : "#ef4444";
|
|
1065
|
-
const chartJsCdn = "https://cdn.jsdelivr.net/npm/chart.js";
|
|
1066
966
|
const htmlContent = `<!DOCTYPE html><html lang="en"><head>
|
|
1067
967
|
<meta charset="UTF-8">
|
|
1068
968
|
<title>Blaze Core Performance Report</title>
|
|
1069
|
-
<script src="
|
|
969
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
1070
970
|
<style>
|
|
1071
971
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0b111e; color: #f8fafc; margin: 0; padding: 2rem; }
|
|
1072
972
|
.container { max-width: 1300px; margin: 0 auto; }
|
|
@@ -1559,14 +1459,6 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
|
|
|
1559
1459
|
function printUsage() {
|
|
1560
1460
|
console.log(`Blaze Core Performance Test CLI Engine
|
|
1561
1461
|
Options:
|
|
1562
|
-
--
|
|
1563
|
-
--threads <count> Number of concurrent threads (default: 10)
|
|
1564
|
-
--duration <seconds> Duration of stress testing in seconds (default: 10)
|
|
1565
|
-
--ramp-up <seconds> Ramp-up speed
|
|
1566
|
-
--ramp-down <seconds> Ramp-down speed
|
|
1567
|
-
--agentic Enable Intelligent Autonomous Agentic Stress Test
|
|
1568
|
-
--correlate Launch dynamic transaction parameter mapping pipeline
|
|
1569
|
-
--baseline <json_file> Input baseline JSON benchmark reference
|
|
1570
|
-
--output <html_file> Target path for exported standalone dashboard`);
|
|
1462
|
+
--threads <count> | --duration <seconds> | --baseline <json_file> | --output <html_file>`);
|
|
1571
1463
|
}
|
|
1572
1464
|
main().catch(console.error);
|
|
Binary file
|