@testsmith/perfornium 0.1.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 +360 -0
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.js +192 -0
- package/dist/cli/commands/distributed.d.ts +11 -0
- package/dist/cli/commands/distributed.js +179 -0
- package/dist/cli/commands/import.d.ts +23 -0
- package/dist/cli/commands/import.js +461 -0
- package/dist/cli/commands/init.d.ts +7 -0
- package/dist/cli/commands/init.js +923 -0
- package/dist/cli/commands/mock.d.ts +7 -0
- package/dist/cli/commands/mock.js +281 -0
- package/dist/cli/commands/report.d.ts +5 -0
- package/dist/cli/commands/report.js +70 -0
- package/dist/cli/commands/run.d.ts +12 -0
- package/dist/cli/commands/run.js +260 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.js +35 -0
- package/dist/cli/commands/worker.d.ts +27 -0
- package/dist/cli/commands/worker.js +320 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +20 -0
- package/dist/config/parser.d.ts +19 -0
- package/dist/config/parser.js +330 -0
- package/dist/config/types/global-config.d.ts +74 -0
- package/dist/config/types/global-config.js +2 -0
- package/dist/config/types/hooks.d.ts +58 -0
- package/dist/config/types/hooks.js +3 -0
- package/dist/config/types/import-types.d.ts +33 -0
- package/dist/config/types/import-types.js +2 -0
- package/dist/config/types/index.d.ts +11 -0
- package/dist/config/types/index.js +27 -0
- package/dist/config/types/load-config.d.ts +32 -0
- package/dist/config/types/load-config.js +9 -0
- package/dist/config/types/output-config.d.ts +10 -0
- package/dist/config/types/output-config.js +2 -0
- package/dist/config/types/report-config.d.ts +10 -0
- package/dist/config/types/report-config.js +2 -0
- package/dist/config/types/runtime-types.d.ts +6 -0
- package/dist/config/types/runtime-types.js +2 -0
- package/dist/config/types/scenario-config.d.ts +30 -0
- package/dist/config/types/scenario-config.js +2 -0
- package/dist/config/types/step-types.d.ts +139 -0
- package/dist/config/types/step-types.js +2 -0
- package/dist/config/types/test-configuration.d.ts +18 -0
- package/dist/config/types/test-configuration.js +2 -0
- package/dist/config/types/worker-config.d.ts +12 -0
- package/dist/config/types/worker-config.js +2 -0
- package/dist/config/validator.d.ts +19 -0
- package/dist/config/validator.js +198 -0
- package/dist/core/csv-data-provider.d.ts +47 -0
- package/dist/core/csv-data-provider.js +265 -0
- package/dist/core/hooks-manager.d.ts +33 -0
- package/dist/core/hooks-manager.js +129 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +11 -0
- package/dist/core/script-executor.d.ts +14 -0
- package/dist/core/script-executor.js +290 -0
- package/dist/core/step-executor.d.ts +41 -0
- package/dist/core/step-executor.js +680 -0
- package/dist/core/test-runner.d.ts +34 -0
- package/dist/core/test-runner.js +465 -0
- package/dist/core/threshold-evaluator.d.ts +43 -0
- package/dist/core/threshold-evaluator.js +170 -0
- package/dist/core/virtual-user-pool.d.ts +42 -0
- package/dist/core/virtual-user-pool.js +136 -0
- package/dist/core/virtual-user.d.ts +51 -0
- package/dist/core/virtual-user.js +488 -0
- package/dist/distributed/coordinator.d.ts +34 -0
- package/dist/distributed/coordinator.js +158 -0
- package/dist/distributed/health-monitor.d.ts +18 -0
- package/dist/distributed/health-monitor.js +72 -0
- package/dist/distributed/load-distributor.d.ts +17 -0
- package/dist/distributed/load-distributor.js +106 -0
- package/dist/distributed/remote-worker.d.ts +37 -0
- package/dist/distributed/remote-worker.js +241 -0
- package/dist/distributed/result-aggregator.d.ts +43 -0
- package/dist/distributed/result-aggregator.js +146 -0
- package/dist/dsl/index.d.ts +3 -0
- package/dist/dsl/index.js +11 -0
- package/dist/dsl/test-builder.d.ts +111 -0
- package/dist/dsl/test-builder.js +514 -0
- package/dist/importers/har-importer.d.ts +17 -0
- package/dist/importers/har-importer.js +172 -0
- package/dist/importers/open-api-importer.d.ts +23 -0
- package/dist/importers/open-api-importer.js +181 -0
- package/dist/importers/wsdl-importer.d.ts +42 -0
- package/dist/importers/wsdl-importer.js +440 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +17 -0
- package/dist/load-patterns/arrivals.d.ts +7 -0
- package/dist/load-patterns/arrivals.js +118 -0
- package/dist/load-patterns/base.d.ts +9 -0
- package/dist/load-patterns/base.js +2 -0
- package/dist/load-patterns/basic.d.ts +7 -0
- package/dist/load-patterns/basic.js +117 -0
- package/dist/load-patterns/stepping.d.ts +6 -0
- package/dist/load-patterns/stepping.js +122 -0
- package/dist/metrics/collector.d.ts +72 -0
- package/dist/metrics/collector.js +662 -0
- package/dist/metrics/types.d.ts +135 -0
- package/dist/metrics/types.js +2 -0
- package/dist/outputs/base.d.ts +7 -0
- package/dist/outputs/base.js +2 -0
- package/dist/outputs/csv.d.ts +13 -0
- package/dist/outputs/csv.js +163 -0
- package/dist/outputs/graphite.d.ts +13 -0
- package/dist/outputs/graphite.js +126 -0
- package/dist/outputs/influxdb.d.ts +12 -0
- package/dist/outputs/influxdb.js +82 -0
- package/dist/outputs/json.d.ts +14 -0
- package/dist/outputs/json.js +107 -0
- package/dist/outputs/streaming-csv.d.ts +37 -0
- package/dist/outputs/streaming-csv.js +254 -0
- package/dist/outputs/streaming-json.d.ts +43 -0
- package/dist/outputs/streaming-json.js +353 -0
- package/dist/outputs/webhook.d.ts +16 -0
- package/dist/outputs/webhook.js +96 -0
- package/dist/protocols/base.d.ts +33 -0
- package/dist/protocols/base.js +2 -0
- package/dist/protocols/rest/handler.d.ts +67 -0
- package/dist/protocols/rest/handler.js +776 -0
- package/dist/protocols/soap/handler.d.ts +12 -0
- package/dist/protocols/soap/handler.js +165 -0
- package/dist/protocols/web/core-web-vitals.d.ts +121 -0
- package/dist/protocols/web/core-web-vitals.js +373 -0
- package/dist/protocols/web/handler.d.ts +50 -0
- package/dist/protocols/web/handler.js +706 -0
- package/dist/recorder/native-recorder.d.ts +14 -0
- package/dist/recorder/native-recorder.js +533 -0
- package/dist/recorder/scenario-recorder.d.ts +55 -0
- package/dist/recorder/scenario-recorder.js +296 -0
- package/dist/reporting/constants.d.ts +94 -0
- package/dist/reporting/constants.js +82 -0
- package/dist/reporting/enhanced-html-generator.d.ts +55 -0
- package/dist/reporting/enhanced-html-generator.js +965 -0
- package/dist/reporting/generator.d.ts +42 -0
- package/dist/reporting/generator.js +1217 -0
- package/dist/reporting/statistics.d.ts +144 -0
- package/dist/reporting/statistics.js +742 -0
- package/dist/reporting/templates/enhanced-report.hbs +2812 -0
- package/dist/reporting/templates/html.hbs +2453 -0
- package/dist/utils/faker-manager.d.ts +55 -0
- package/dist/utils/faker-manager.js +166 -0
- package/dist/utils/file-manager.d.ts +33 -0
- package/dist/utils/file-manager.js +154 -0
- package/dist/utils/handlebars-manager.d.ts +42 -0
- package/dist/utils/handlebars-manager.js +172 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.js +46 -0
- package/dist/utils/template.d.ts +80 -0
- package/dist/utils/template.js +513 -0
- package/dist/utils/test-output-writer.d.ts +56 -0
- package/dist/utils/test-output-writer.js +643 -0
- package/dist/utils/time.d.ts +3 -0
- package/dist/utils/time.js +23 -0
- package/dist/utils/timestamp-helper.d.ts +17 -0
- package/dist/utils/timestamp-helper.js +53 -0
- package/dist/workers/manager.d.ts +18 -0
- package/dist/workers/manager.js +95 -0
- package/dist/workers/server.d.ts +21 -0
- package/dist/workers/server.js +205 -0
- package/dist/workers/worker.d.ts +19 -0
- package/dist/workers/worker.js +147 -0
- package/package.json +102 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare class WorkerServer {
|
|
2
|
+
private server;
|
|
3
|
+
private host;
|
|
4
|
+
private port;
|
|
5
|
+
private status;
|
|
6
|
+
private activeRunner;
|
|
7
|
+
private preparedConfig;
|
|
8
|
+
private completedRunner;
|
|
9
|
+
constructor(host?: string, port?: number);
|
|
10
|
+
private handleRequest;
|
|
11
|
+
private handleHealth;
|
|
12
|
+
private handleStatus;
|
|
13
|
+
private handlePrepare;
|
|
14
|
+
private handleStart;
|
|
15
|
+
private handleResults;
|
|
16
|
+
private handleStop;
|
|
17
|
+
private readRequestBody;
|
|
18
|
+
private sendJson;
|
|
19
|
+
private sendError;
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
stop(): Promise<void>;
|
|
22
|
+
getStatus(): any;
|
|
23
|
+
}
|
|
24
|
+
export declare function workerCommand(options: {
|
|
25
|
+
port?: string;
|
|
26
|
+
host?: string;
|
|
27
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.WorkerServer = void 0;
|
|
37
|
+
exports.workerCommand = workerCommand;
|
|
38
|
+
const logger_1 = require("../../utils/logger");
|
|
39
|
+
const http = __importStar(require("http"));
|
|
40
|
+
const url_1 = require("url");
|
|
41
|
+
const test_runner_1 = require("../../core/test-runner");
|
|
42
|
+
class WorkerServer {
|
|
43
|
+
constructor(host = 'localhost', port = 8080) {
|
|
44
|
+
this.activeRunner = null;
|
|
45
|
+
this.preparedConfig = null;
|
|
46
|
+
this.completedRunner = null;
|
|
47
|
+
this.host = host;
|
|
48
|
+
this.port = port;
|
|
49
|
+
this.status = {
|
|
50
|
+
connected: true,
|
|
51
|
+
running: false,
|
|
52
|
+
virtualUsers: 0,
|
|
53
|
+
requestsPerSecond: 0,
|
|
54
|
+
responseTime: 0,
|
|
55
|
+
errorRate: 0
|
|
56
|
+
};
|
|
57
|
+
this.server = http.createServer((req, res) => {
|
|
58
|
+
this.handleRequest(req, res);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async handleRequest(req, res) {
|
|
62
|
+
// Set CORS headers
|
|
63
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
64
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
65
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
66
|
+
if (req.method === 'OPTIONS') {
|
|
67
|
+
res.writeHead(200);
|
|
68
|
+
res.end();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const url = new url_1.URL(req.url || '/', `http://${req.headers.host}`);
|
|
72
|
+
const method = req.method || 'GET';
|
|
73
|
+
try {
|
|
74
|
+
switch (`${method} ${url.pathname}`) {
|
|
75
|
+
case 'GET /health':
|
|
76
|
+
await this.handleHealth(res);
|
|
77
|
+
break;
|
|
78
|
+
case 'GET /status':
|
|
79
|
+
await this.handleStatus(res);
|
|
80
|
+
break;
|
|
81
|
+
case 'POST /prepare':
|
|
82
|
+
await this.handlePrepare(req, res);
|
|
83
|
+
break;
|
|
84
|
+
case 'POST /start':
|
|
85
|
+
await this.handleStart(req, res);
|
|
86
|
+
break;
|
|
87
|
+
case 'GET /results':
|
|
88
|
+
await this.handleResults(res);
|
|
89
|
+
break;
|
|
90
|
+
case 'POST /stop':
|
|
91
|
+
await this.handleStop(res);
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
this.sendError(res, 404, 'Not Found', `Endpoint ${method} ${url.pathname} not found`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
logger_1.logger.error(`â Error handling ${method} ${url.pathname}:`, error);
|
|
99
|
+
this.sendError(res, 500, 'Internal Server Error', error.message);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async handleHealth(res) {
|
|
103
|
+
this.sendJson(res, 200, {
|
|
104
|
+
status: 'healthy',
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
uptime: process.uptime(),
|
|
107
|
+
memory: process.memoryUsage()
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async handleStatus(res) {
|
|
111
|
+
this.sendJson(res, 200, {
|
|
112
|
+
...this.status,
|
|
113
|
+
timestamp: new Date().toISOString(),
|
|
114
|
+
uptime: process.uptime(),
|
|
115
|
+
activeRunner: this.activeRunner ? 'running' : 'idle'
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async handlePrepare(req, res) {
|
|
119
|
+
const body = await this.readRequestBody(req);
|
|
120
|
+
try {
|
|
121
|
+
const testConfig = JSON.parse(body);
|
|
122
|
+
this.preparedConfig = testConfig;
|
|
123
|
+
logger_1.logger.info(`đ Test prepared: ${testConfig.name}`);
|
|
124
|
+
this.sendJson(res, 200, {
|
|
125
|
+
status: 'prepared',
|
|
126
|
+
testName: testConfig.name,
|
|
127
|
+
timestamp: new Date().toISOString()
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.sendError(res, 400, 'Bad Request', `Invalid test configuration: ${error.message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async handleStart(req, res) {
|
|
135
|
+
if (!this.preparedConfig) {
|
|
136
|
+
this.sendError(res, 400, 'Bad Request', 'No test configuration prepared. Call /prepare first.');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (this.status.running) {
|
|
140
|
+
this.sendError(res, 409, 'Conflict', 'Test is already running');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const body = await this.readRequestBody(req);
|
|
145
|
+
let startOptions = {};
|
|
146
|
+
if (body) {
|
|
147
|
+
startOptions = JSON.parse(body);
|
|
148
|
+
}
|
|
149
|
+
// If startTime is provided (for synchronized start), wait until that time
|
|
150
|
+
if (startOptions.startTime) {
|
|
151
|
+
const delay = startOptions.startTime - Date.now();
|
|
152
|
+
if (delay > 0) {
|
|
153
|
+
logger_1.logger.info(`â° Waiting ${delay}ms for synchronized start...`);
|
|
154
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
this.activeRunner = new test_runner_1.TestRunner(this.preparedConfig);
|
|
158
|
+
this.status.running = true;
|
|
159
|
+
const { getPrimaryLoadPhase } = await Promise.resolve().then(() => __importStar(require('../../config/types/load-config')));
|
|
160
|
+
const primaryPhase = getPrimaryLoadPhase(this.preparedConfig.load);
|
|
161
|
+
this.status.virtualUsers = primaryPhase.virtual_users || primaryPhase.vus || 1;
|
|
162
|
+
logger_1.logger.info(`đ Starting test: ${this.preparedConfig.name}`);
|
|
163
|
+
// Start the test asynchronously and collect results
|
|
164
|
+
this.activeRunner.run().then(() => {
|
|
165
|
+
this.status.running = false;
|
|
166
|
+
logger_1.logger.info(`â
Test completed: ${this.preparedConfig?.name}`);
|
|
167
|
+
// Store completed runner for results retrieval
|
|
168
|
+
this.completedRunner = this.activeRunner;
|
|
169
|
+
// Get final metrics and store them for retrieval
|
|
170
|
+
if (this.activeRunner) {
|
|
171
|
+
const metrics = this.activeRunner.getMetrics();
|
|
172
|
+
this.status.responseTime = metrics.getSummary().avg_response_time || 0;
|
|
173
|
+
this.status.requestsPerSecond = metrics.getSummary().requests_per_second || 0;
|
|
174
|
+
this.status.errorRate = (1 - (metrics.getSummary().success_rate / 100)) * 100;
|
|
175
|
+
}
|
|
176
|
+
this.activeRunner = null;
|
|
177
|
+
}).catch((error) => {
|
|
178
|
+
this.status.running = false;
|
|
179
|
+
this.activeRunner = null;
|
|
180
|
+
logger_1.logger.error(`â Test failed: ${error.message}`);
|
|
181
|
+
});
|
|
182
|
+
this.sendJson(res, 200, {
|
|
183
|
+
status: 'started',
|
|
184
|
+
testName: this.preparedConfig.name,
|
|
185
|
+
virtualUsers: this.status.virtualUsers,
|
|
186
|
+
timestamp: new Date().toISOString()
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
this.status.running = false;
|
|
191
|
+
this.sendError(res, 500, 'Internal Server Error', `Failed to start test: ${error.message}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async handleResults(res) {
|
|
195
|
+
if (!this.completedRunner) {
|
|
196
|
+
this.sendError(res, 404, 'Not Found', 'No completed test results available');
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const metrics = this.completedRunner.getMetrics();
|
|
201
|
+
const summary = metrics.getSummary();
|
|
202
|
+
const results = metrics.getResults();
|
|
203
|
+
this.sendJson(res, 200, {
|
|
204
|
+
summary,
|
|
205
|
+
results,
|
|
206
|
+
worker: {
|
|
207
|
+
host: this.host,
|
|
208
|
+
port: this.port,
|
|
209
|
+
timestamp: new Date().toISOString()
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
this.sendError(res, 500, 'Internal Server Error', `Failed to get results: ${error.message}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async handleStop(res) {
|
|
218
|
+
if (!this.status.running || !this.activeRunner) {
|
|
219
|
+
this.sendError(res, 400, 'Bad Request', 'No test is currently running');
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
await this.activeRunner.stop();
|
|
224
|
+
this.status.running = false;
|
|
225
|
+
this.activeRunner = null;
|
|
226
|
+
logger_1.logger.info(`âšī¸ Test stopped`);
|
|
227
|
+
this.sendJson(res, 200, {
|
|
228
|
+
status: 'stopped',
|
|
229
|
+
timestamp: new Date().toISOString()
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
this.sendError(res, 500, 'Internal Server Error', `Failed to stop test: ${error.message}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async readRequestBody(req) {
|
|
237
|
+
return new Promise((resolve) => {
|
|
238
|
+
let body = '';
|
|
239
|
+
req.on('data', chunk => {
|
|
240
|
+
body += chunk.toString();
|
|
241
|
+
});
|
|
242
|
+
req.on('end', () => {
|
|
243
|
+
resolve(body);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
sendJson(res, statusCode, data) {
|
|
248
|
+
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
249
|
+
res.end(JSON.stringify(data));
|
|
250
|
+
}
|
|
251
|
+
sendError(res, statusCode, error, message) {
|
|
252
|
+
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
253
|
+
res.end(JSON.stringify({
|
|
254
|
+
error,
|
|
255
|
+
message,
|
|
256
|
+
timestamp: new Date().toISOString()
|
|
257
|
+
}));
|
|
258
|
+
}
|
|
259
|
+
async start() {
|
|
260
|
+
return new Promise((resolve) => {
|
|
261
|
+
this.server.listen(this.port, this.host, () => {
|
|
262
|
+
logger_1.logger.info(`đ Worker server started on ${this.host}:${this.port}`);
|
|
263
|
+
logger_1.logger.info(`đ Available endpoints:`);
|
|
264
|
+
logger_1.logger.info(` GET http://${this.host}:${this.port}/health`);
|
|
265
|
+
logger_1.logger.info(` GET http://${this.host}:${this.port}/status`);
|
|
266
|
+
logger_1.logger.info(` POST http://${this.host}:${this.port}/prepare`);
|
|
267
|
+
logger_1.logger.info(` POST http://${this.host}:${this.port}/start`);
|
|
268
|
+
logger_1.logger.info(` POST http://${this.host}:${this.port}/stop`);
|
|
269
|
+
logger_1.logger.info(` GET http://${this.host}:${this.port}/results`);
|
|
270
|
+
resolve();
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async stop() {
|
|
275
|
+
return new Promise((resolve) => {
|
|
276
|
+
if (this.activeRunner) {
|
|
277
|
+
this.activeRunner.stop().catch(err => logger_1.logger.error('â Error stopping runner:', err));
|
|
278
|
+
}
|
|
279
|
+
this.server.close(() => {
|
|
280
|
+
logger_1.logger.info('đ Worker server stopped');
|
|
281
|
+
resolve();
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
getStatus() {
|
|
286
|
+
return {
|
|
287
|
+
host: this.host,
|
|
288
|
+
port: this.port,
|
|
289
|
+
status: this.status,
|
|
290
|
+
uptime: process.uptime(),
|
|
291
|
+
memory: process.memoryUsage()
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
exports.WorkerServer = WorkerServer;
|
|
296
|
+
// Updated worker command function
|
|
297
|
+
async function workerCommand(options) {
|
|
298
|
+
const port = parseInt(options.port || '8080');
|
|
299
|
+
const host = options.host || 'localhost';
|
|
300
|
+
const workerServer = new WorkerServer(host, port);
|
|
301
|
+
// Handle graceful shutdown
|
|
302
|
+
const shutdown = async () => {
|
|
303
|
+
logger_1.logger.info('đ Received shutdown signal, stopping worker...');
|
|
304
|
+
await workerServer.stop();
|
|
305
|
+
process.exit(0);
|
|
306
|
+
};
|
|
307
|
+
process.on('SIGINT', shutdown);
|
|
308
|
+
process.on('SIGTERM', shutdown);
|
|
309
|
+
try {
|
|
310
|
+
await workerServer.start();
|
|
311
|
+
// Keep the process alive
|
|
312
|
+
process.on('exit', () => {
|
|
313
|
+
logger_1.logger.info('đ Worker process exiting');
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
logger_1.logger.error(`â Failed to start worker: ${error.message}`);
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ConfigParser = void 0;
|
|
18
|
+
var parser_1 = require("./parser");
|
|
19
|
+
Object.defineProperty(exports, "ConfigParser", { enumerable: true, get: function () { return parser_1.ConfigParser; } });
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TestConfiguration } from './types';
|
|
2
|
+
export declare class ConfigParser {
|
|
3
|
+
private templateProcessor;
|
|
4
|
+
parse(configPath: string, environment?: string): Promise<TestConfiguration>;
|
|
5
|
+
private parseTypeScript;
|
|
6
|
+
private evaluatePlainTypeScript;
|
|
7
|
+
private setupBaseDirectories;
|
|
8
|
+
private setupFaker;
|
|
9
|
+
private parseContent;
|
|
10
|
+
private validateRequiredFields;
|
|
11
|
+
private validateCSVConfig;
|
|
12
|
+
private loadEnvironmentConfig;
|
|
13
|
+
private mergeConfigs;
|
|
14
|
+
processTemplates(config: TestConfiguration, _context: {
|
|
15
|
+
env: NodeJS.ProcessEnv;
|
|
16
|
+
timestamp: number;
|
|
17
|
+
datetime: string;
|
|
18
|
+
}): TestConfiguration;
|
|
19
|
+
}
|