testeranto 0.47.30 → 0.47.32
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/common/Node.js +13 -21
- package/dist/common/Project.js +228 -208
- package/dist/common/Web.js +59 -13
- package/dist/common/core.js +6 -1
- package/dist/common/electron.js +14 -2
- package/dist/common/preload.js +20 -0
- package/dist/common/subPackages/react/jsx/index.js +26 -0
- package/dist/common/subPackages/react/jsx/node.js +2 -11
- package/dist/common/subPackages/react/jsx/web.js +2 -11
- package/dist/common/subPackages/react-dom/component/node.js +78 -34
- package/dist/common/subPackages/react-dom/component/web.js +50 -46
- package/dist/common/subPackages/react-dom/jsx/node.js +101 -0
- package/dist/common/subPackages/react-test-renderer/component/index.js +78 -0
- package/dist/common/subPackages/react-test-renderer/component/node.js +8 -0
- package/dist/common/subPackages/react-test-renderer/component/web.js +8 -0
- package/dist/common/subPackages/{react-test-render/component/web.js → react-test-renderer/jsx/index.js} +3 -3
- package/dist/common/subPackages/react-test-renderer/jsx/node.js +10 -0
- package/dist/common/subPackages/react-test-renderer/jsx/web.js +10 -0
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/Node.js +13 -21
- package/dist/module/Project.js +228 -208
- package/dist/module/Web.js +59 -13
- package/dist/module/core.js +6 -1
- package/dist/module/electron.js +14 -2
- package/dist/module/preload.js +20 -0
- package/dist/module/subPackages/react/jsx/index.js +22 -0
- package/dist/module/subPackages/react/jsx/node.js +2 -11
- package/dist/module/subPackages/react/jsx/web.js +2 -11
- package/dist/module/subPackages/react-dom/component/node.js +75 -34
- package/dist/module/subPackages/react-dom/component/web.js +50 -46
- package/dist/module/subPackages/react-dom/jsx/node.js +93 -0
- package/dist/module/subPackages/react-test-renderer/component/index.js +52 -0
- package/dist/module/subPackages/react-test-renderer/component/node.js +3 -0
- package/dist/module/subPackages/react-test-renderer/component/web.js +3 -0
- package/dist/module/subPackages/react-test-renderer/fc/node.js +22 -0
- package/dist/module/subPackages/{react-test-render/component/web.js → react-test-renderer/jsx/index.js} +2 -3
- package/dist/module/subPackages/react-test-renderer/jsx/node.js +5 -0
- package/dist/module/subPackages/react-test-renderer/jsx/web.js +5 -0
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/types/Project.d.ts +2 -1
- package/dist/types/core.d.ts +1 -0
- package/dist/types/subPackages/react/jsx/index.d.ts +15 -0
- package/dist/types/subPackages/react/jsx/node.d.ts +3 -10
- package/dist/types/subPackages/react/jsx/web.d.ts +3 -11
- package/dist/types/subPackages/react-dom/component/node.d.ts +9 -14
- package/dist/types/subPackages/react-dom/component/web.d.ts +1 -1
- package/dist/types/subPackages/react-dom/jsx/node.d.ts +14 -0
- package/dist/types/subPackages/react-dom/jsx/web.d.ts +0 -1
- package/dist/types/subPackages/react-test-renderer/component/index.d.ts +20 -0
- package/dist/types/subPackages/react-test-renderer/component/node.d.ts +9 -0
- package/dist/types/subPackages/react-test-renderer/component/web.d.ts +9 -0
- package/dist/types/subPackages/react-test-renderer/jsx/index.d.ts +15 -0
- package/dist/types/subPackages/react-test-renderer/jsx/node.d.ts +4 -0
- package/dist/types/subPackages/react-test-renderer/jsx/web.d.ts +4 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +71 -7
- package/src/Node.ts +18 -30
- package/src/Project.ts +292 -274
- package/src/Web.ts +78 -16
- package/src/core.ts +7 -1
- package/src/electron.ts +18 -2
- package/src/preload.ts +23 -0
- package/src/subPackages/react/jsx/index.ts +64 -0
- package/src/subPackages/react/jsx/node.ts +7 -36
- package/src/subPackages/react/jsx/web.ts +7 -38
- package/src/subPackages/react-dom/component/node.ts +85 -54
- package/src/subPackages/react-dom/component/web.ts +86 -76
- package/src/subPackages/react-dom/jsx/node.ts +150 -0
- package/src/subPackages/react-test-renderer/component/index.ts +101 -0
- package/src/subPackages/react-test-renderer/component/node.ts +30 -0
- package/src/subPackages/react-test-renderer/component/web.ts +30 -0
- package/src/subPackages/react-test-renderer/fc/node.tsx +77 -0
- package/src/subPackages/react-test-renderer/jsx/index.ts +51 -0
- package/src/subPackages/react-test-renderer/jsx/node.ts +31 -0
- package/src/subPackages/react-test-renderer/jsx/web.ts +31 -0
- package/dist/common/subPackages/react-test-render/component/node.js +0 -44
- package/dist/common/subPackages/react-test-render/jsx/node.js +0 -46
- package/dist/common/subPackages/react-test-render/jsx/web.js +0 -46
- package/dist/module/subPackages/react-test-render/component/node.js +0 -16
- package/dist/module/subPackages/react-test-render/jsx/node.js +0 -16
- package/dist/module/subPackages/react-test-render/jsx/web.js +0 -16
- package/dist/types/subPackages/react-test-render/component/node.d.ts +0 -19
- package/dist/types/subPackages/react-test-render/component/web.d.ts +0 -20
- package/dist/types/subPackages/react-test-render/jsx/node.d.ts +0 -20
- package/dist/types/subPackages/react-test-render/jsx/web.d.ts +0 -20
- package/src/subPackages/react-test-render/component/node.ts +0 -80
- package/src/subPackages/react-test-render/component/web.ts +0 -78
- package/src/subPackages/react-test-render/jsx/node.ts +0 -75
- package/src/subPackages/react-test-render/jsx/web.ts +0 -75
package/src/Project.ts
CHANGED
|
@@ -106,6 +106,12 @@ export class ITProject {
|
|
|
106
106
|
this.initiateShutdown("'q' command")
|
|
107
107
|
}
|
|
108
108
|
});
|
|
109
|
+
process.stdin.on('keypress', (str, key) => {
|
|
110
|
+
if (key.name === 'x') {
|
|
111
|
+
console.log("Shutting down hard!")
|
|
112
|
+
process.exit(-1)
|
|
113
|
+
}
|
|
114
|
+
});
|
|
109
115
|
|
|
110
116
|
import(testPath).then((tests) => {
|
|
111
117
|
this.tests = tests.default;
|
|
@@ -184,6 +190,7 @@ export class ITProject {
|
|
|
184
190
|
setup(build) {
|
|
185
191
|
build.onEnd(result => {
|
|
186
192
|
console.log(`node build ended with ${result.errors.length} errors`);
|
|
193
|
+
console.log(result)
|
|
187
194
|
result.errors.length !== 0 && process.exit(-1);
|
|
188
195
|
// HERE: somehow restart the server from here, e.g., by sending a signal that you trap and react to inside the server.
|
|
189
196
|
})
|
|
@@ -237,6 +244,7 @@ export class ITProject {
|
|
|
237
244
|
setup(build) {
|
|
238
245
|
build.onEnd(result => {
|
|
239
246
|
console.log(`web build ended with ${result.errors.length} errors`);
|
|
247
|
+
console.log(result)
|
|
240
248
|
result.errors.length !== 0 && process.exit(-1);
|
|
241
249
|
// HERE: somehow restart the server from here, e.g., by sending a signal that you trap and react to inside the server.
|
|
242
250
|
})
|
|
@@ -290,197 +298,215 @@ export class ITProject {
|
|
|
290
298
|
`)
|
|
291
299
|
|
|
292
300
|
Promise.all([
|
|
293
|
-
|
|
294
301
|
esbuild.context(esbuildConfigNode).then(async (nodeContext) => {
|
|
295
302
|
await nodeContext.watch();
|
|
296
303
|
}),
|
|
297
|
-
|
|
298
304
|
esbuild.context(esbuildConfigWeb).then(async (esbuildWeb) => {
|
|
299
305
|
await esbuildWeb.watch();
|
|
300
306
|
})
|
|
301
|
-
])
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
console.error(err);
|
|
306
|
-
process.exit(-1);
|
|
307
|
+
]).then(() => {
|
|
308
|
+
if (config.devMode === false) {
|
|
309
|
+
console.log("Your tests were built but not run because devMode was false. Exiting gracefully");
|
|
310
|
+
process.exit(0);
|
|
307
311
|
} else {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
pm2.connect(async (err) => {
|
|
313
|
+
if (err) {
|
|
314
|
+
console.error(err);
|
|
315
|
+
process.exit(-1);
|
|
316
|
+
} else {
|
|
317
|
+
console.log(`pm2 is connected`);
|
|
318
|
+
}
|
|
319
|
+
// run a websocket as an alternative to node IPC
|
|
320
|
+
webSocketServer = new WebSocketServer({
|
|
321
|
+
port: 8080,
|
|
322
|
+
host: "localhost",
|
|
323
|
+
});
|
|
315
324
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
325
|
+
webSocketServer.on('open', () => {
|
|
326
|
+
console.log('open');
|
|
327
|
+
// process.exit()
|
|
328
|
+
});
|
|
320
329
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
330
|
+
webSocketServer.on('close', (data) => {
|
|
331
|
+
console.log('webSocketServer close: %s', data);
|
|
332
|
+
// process.exit()
|
|
333
|
+
});
|
|
325
334
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
335
|
+
webSocketServer.on('listening', () => {
|
|
336
|
+
console.log("webSocketServer listening", webSocketServer.address());
|
|
337
|
+
// process.exit()
|
|
338
|
+
});
|
|
330
339
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
webSocket.on('message', (webSocketData) => {
|
|
335
|
-
console.log('webSocket message: %s', webSocketData);
|
|
336
|
-
const payload = webSocketData.valueOf() as { type: string, data: ITTestResourceRequirement };
|
|
337
|
-
const name = payload.data.name;
|
|
338
|
-
const messageType = payload.type;
|
|
339
|
-
const requestedResources = payload.data;
|
|
340
|
-
|
|
341
|
-
this.websockets[name] = webSocket
|
|
342
|
-
console.log('connected: ' + name + ' in ' + Object.getOwnPropertyNames(this.websockets))
|
|
343
|
-
|
|
344
|
-
if (messageType === "testeranto:hola") {
|
|
345
|
-
console.log("hola WS", requestedResources);
|
|
346
|
-
this.requestResource(requestedResources, 'ws');
|
|
347
|
-
} else if (messageType === "testeranto:adios") {
|
|
348
|
-
console.log("adios WS", name);
|
|
349
|
-
this.releaseTestResources(payload as any);
|
|
350
|
-
}
|
|
340
|
+
webSocketServer.on('connection', (webSocket: WebSocket) => {
|
|
341
|
+
console.log('webSocketServer connection');
|
|
351
342
|
|
|
352
|
-
|
|
353
|
-
|
|
343
|
+
webSocket.on('message', (webSocketData) => {
|
|
344
|
+
// console.log('webSocket message: %s', webSocketData);
|
|
345
|
+
const payload = JSON.parse(webSocketData.valueOf().toString() as any);
|
|
354
346
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
347
|
+
// console.log('webSocket payload', JSON.stringify(payload.data.testResourceConfiguration.name, null, 2));
|
|
348
|
+
// as {
|
|
349
|
+
// type: string,
|
|
350
|
+
// data: ITTestResourceRequirement & {
|
|
351
|
+
// testResourceConfiguration: {
|
|
352
|
+
// name: string;
|
|
353
|
+
// }
|
|
354
|
+
// }
|
|
355
|
+
// };
|
|
358
356
|
|
|
359
|
-
|
|
360
|
-
const filesToLookup = this.tests
|
|
361
|
-
.map(([p, rt]) => {
|
|
362
|
-
const filepath = makePath(p, rt);
|
|
363
|
-
return {
|
|
364
|
-
filepath,
|
|
365
|
-
exists: fsExists(filepath),
|
|
366
|
-
};
|
|
367
|
-
});
|
|
368
|
-
const allFilesExist = (
|
|
369
|
-
await Promise.all(filesToLookup.map((f) => f.exists))
|
|
370
|
-
).every((b) => b);
|
|
357
|
+
const messageType = payload.type;
|
|
371
358
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
console.log(f.exists, "\t", f.filepath);
|
|
376
|
-
})
|
|
359
|
+
if (messageType === "testeranto:hola") {
|
|
360
|
+
const name = payload.data.requirement.name;
|
|
361
|
+
const requestedResources = payload.data;
|
|
377
362
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
'ipc'
|
|
387
|
-
);
|
|
388
|
-
});
|
|
363
|
+
this.websockets[name] = webSocket
|
|
364
|
+
console.log('hola WS! connected: ' + name + ' in ' + Object.getOwnPropertyNames(this.websockets))
|
|
365
|
+
this.requestResource(requestedResources.requirement, 'ws');
|
|
366
|
+
|
|
367
|
+
} else if (messageType === "testeranto:adios") {
|
|
368
|
+
console.log("adios WS", payload.data.testResourceConfiguration.name);
|
|
369
|
+
this.releaseTestResourceWs(payload as any);
|
|
370
|
+
}
|
|
389
371
|
|
|
390
|
-
pm2_bus.on("testeranto:adios", (payload: IAdiosIPC) => {
|
|
391
|
-
console.log("adios IPC", payload);
|
|
392
|
-
this.releaseTestResources(payload.data);
|
|
393
372
|
});
|
|
394
373
|
});
|
|
395
374
|
|
|
396
|
-
|
|
397
|
-
.
|
|
398
|
-
|
|
399
|
-
const script = makePath(inputFilePath, runtime);
|
|
400
|
-
const partialTestResourceByCommandLineArg = `${script} '${JSON.stringify(
|
|
401
|
-
{
|
|
402
|
-
name: inputFilePath,
|
|
403
|
-
ports: [],
|
|
404
|
-
fs: path.resolve(
|
|
405
|
-
process.cwd(),
|
|
406
|
-
config.outdir,
|
|
407
|
-
inputFilePath
|
|
408
|
-
),
|
|
409
|
-
}
|
|
410
|
-
)}'`;
|
|
411
|
-
|
|
412
|
-
if (runtime === "web") {
|
|
413
|
-
const fileAsList = inputFilePath.split("/");
|
|
414
|
-
const fileListHead = fileAsList.slice(0, -1);
|
|
415
|
-
const fname = fileAsList[fileAsList.length - 1];
|
|
416
|
-
const fnameOnly = fname.split(".").slice(0, -1).join(".");
|
|
417
|
-
const htmlFile = [config.outdir, ...fileListHead, `${fnameOnly}.html`].join("/");
|
|
418
|
-
const jsFile = htmlFile.split(".html")[0] + ".mjs"
|
|
419
|
-
console.log("watching", jsFile);
|
|
420
|
-
|
|
421
|
-
pm2.start(
|
|
422
|
-
{
|
|
423
|
-
|
|
424
|
-
script: `yarn electron node_modules/testeranto/dist/common/electron.js ${htmlFile} '${JSON.stringify(
|
|
425
|
-
{
|
|
426
|
-
name: inputFilePath,
|
|
427
|
-
ports: [],
|
|
428
|
-
fs:
|
|
429
|
-
path.resolve(
|
|
430
|
-
process.cwd(),
|
|
431
|
-
config.outdir,
|
|
432
|
-
inputFilePath
|
|
433
|
-
),
|
|
434
|
-
}
|
|
435
|
-
)}'`,
|
|
436
|
-
name: inputFilePath,
|
|
437
|
-
autorestart: false,
|
|
438
|
-
args: partialTestResourceByCommandLineArg,
|
|
439
|
-
watch: [jsFile],
|
|
440
|
-
},
|
|
441
|
-
(err, proc) => {
|
|
442
|
-
if (err) {
|
|
443
|
-
console.error(err);
|
|
444
|
-
return pm2.disconnect();
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
);
|
|
375
|
+
const makePath = (fPath: string, rt: IRunTime): string => {
|
|
376
|
+
return path.resolve("./" + config.outdir + "/" + fPath.replace(path.extname(fPath), "") + ".mjs");
|
|
377
|
+
};
|
|
448
378
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
379
|
+
const bootInterval = setInterval(async () => {
|
|
380
|
+
const filesToLookup = this.tests
|
|
381
|
+
.map(([p, rt]) => {
|
|
382
|
+
const filepath = makePath(p, rt);
|
|
383
|
+
return {
|
|
384
|
+
filepath,
|
|
385
|
+
exists: fsExists(filepath),
|
|
386
|
+
};
|
|
387
|
+
});
|
|
388
|
+
const allFilesExist = (
|
|
389
|
+
await Promise.all(filesToLookup.map((f) => f.exists))
|
|
390
|
+
).every((b) => b);
|
|
391
|
+
|
|
392
|
+
if (!allFilesExist) {
|
|
393
|
+
console.log(this.spinner(), "waiting for files to build...")
|
|
394
|
+
filesToLookup.forEach((f) => {
|
|
395
|
+
console.log(f.exists, "\t", f.filepath);
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
} else {
|
|
399
|
+
clearInterval(bootInterval);
|
|
400
|
+
|
|
401
|
+
pm2.launchBus((err, pm2_bus) => {
|
|
402
|
+
pm2_bus.on("testeranto:hola", (packet: { data: { requirement: ITTestResourceRequirement } }) => {
|
|
403
|
+
console.log("hola IPC", packet);
|
|
404
|
+
this.requestResource(
|
|
405
|
+
packet.data.requirement,
|
|
406
|
+
'ipc'
|
|
407
|
+
);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
pm2_bus.on("testeranto:adios", (payload: IAdiosIPC) => {
|
|
411
|
+
this.releaseTestResourcePm2(payload.data);
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
this
|
|
416
|
+
.tests
|
|
417
|
+
.reduce((m, [inputFilePath, runtime]) => {
|
|
418
|
+
const script = makePath(inputFilePath, runtime);
|
|
419
|
+
const partialTestResourceByCommandLineArg = `${script} '${JSON.stringify(
|
|
453
420
|
{
|
|
454
421
|
name: inputFilePath,
|
|
455
422
|
ports: [],
|
|
456
|
-
fs:
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
),
|
|
423
|
+
fs: path.resolve(
|
|
424
|
+
process.cwd(),
|
|
425
|
+
config.outdir,
|
|
426
|
+
inputFilePath
|
|
427
|
+
),
|
|
462
428
|
}
|
|
463
|
-
)}'
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
429
|
+
)}'`;
|
|
430
|
+
|
|
431
|
+
if (runtime === "web") {
|
|
432
|
+
const fileAsList = inputFilePath.split("/");
|
|
433
|
+
const fileListHead = fileAsList.slice(0, -1);
|
|
434
|
+
const fname = fileAsList[fileAsList.length - 1];
|
|
435
|
+
const fnameOnly = fname.split(".").slice(0, -1).join(".");
|
|
436
|
+
const htmlFile = [config.outdir, ...fileListHead, `${fnameOnly}.html`].join("/");
|
|
437
|
+
const jsFile = path.resolve(htmlFile.split(".html")[0] + ".mjs")
|
|
438
|
+
console.log("watching", jsFile);
|
|
439
|
+
|
|
440
|
+
pm2.start(
|
|
441
|
+
{
|
|
475
442
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
443
|
+
script: `yarn electron node_modules/testeranto/dist/common/electron.js ${htmlFile} '${JSON.stringify(
|
|
444
|
+
{
|
|
445
|
+
scheduled: true,
|
|
446
|
+
name: inputFilePath,
|
|
447
|
+
ports: [],
|
|
448
|
+
fs:
|
|
449
|
+
path.resolve(
|
|
450
|
+
process.cwd(),
|
|
451
|
+
config.outdir,
|
|
452
|
+
inputFilePath
|
|
453
|
+
),
|
|
454
|
+
}
|
|
455
|
+
)}'`,
|
|
456
|
+
name: inputFilePath,
|
|
457
|
+
autorestart: false,
|
|
458
|
+
args: partialTestResourceByCommandLineArg,
|
|
459
|
+
watch: [jsFile],
|
|
460
|
+
},
|
|
461
|
+
(err, proc) => {
|
|
462
|
+
if (err) {
|
|
463
|
+
console.error(err);
|
|
464
|
+
return pm2.disconnect();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
} else if (runtime === "node") {
|
|
470
|
+
const resolvedPath = path.resolve(script);
|
|
483
471
|
|
|
472
|
+
console.log("watching", resolvedPath);
|
|
473
|
+
pm2.start({
|
|
474
|
+
|
|
475
|
+
name: inputFilePath,
|
|
476
|
+
script: `node ${resolvedPath} '${JSON.stringify(
|
|
477
|
+
{
|
|
478
|
+
scheduled: true,
|
|
479
|
+
name: inputFilePath,
|
|
480
|
+
ports: [],
|
|
481
|
+
fs:
|
|
482
|
+
path.resolve(
|
|
483
|
+
process.cwd(),
|
|
484
|
+
config.outdir,
|
|
485
|
+
inputFilePath
|
|
486
|
+
),
|
|
487
|
+
}
|
|
488
|
+
)}'`,
|
|
489
|
+
autorestart: false,
|
|
490
|
+
watch: [resolvedPath],
|
|
491
|
+
args: partialTestResourceByCommandLineArg
|
|
492
|
+
|
|
493
|
+
}, (err, proc) => {
|
|
494
|
+
if (err) {
|
|
495
|
+
console.error(err);
|
|
496
|
+
return pm2.disconnect();
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
this.exitCodes[inputFilePath] = null;
|
|
502
|
+
return [inputFilePath, ...m];
|
|
503
|
+
}, []);
|
|
504
|
+
setInterval(this.mainLoop, TIMEOUT).unref();
|
|
505
|
+
}
|
|
506
|
+
}, TIMEOUT).unref();
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
})
|
|
484
510
|
})
|
|
485
511
|
})
|
|
486
512
|
}
|
|
@@ -511,11 +537,39 @@ export class ITProject {
|
|
|
511
537
|
}
|
|
512
538
|
|
|
513
539
|
private shutdown() {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
540
|
+
|
|
541
|
+
let i = 0;
|
|
542
|
+
new Promise((res, reh) => {
|
|
543
|
+
console.log("final results: ");
|
|
544
|
+
const procsTable: any[] = [];
|
|
545
|
+
pm2.list((err, procs) => {
|
|
546
|
+
procs.forEach((proc, ndx) => {
|
|
547
|
+
|
|
548
|
+
const exitCode = this.exitCodes[proc.name as string]
|
|
549
|
+
if (exitCode !== 0) {
|
|
550
|
+
i++;
|
|
551
|
+
}
|
|
552
|
+
procsTable.push({
|
|
553
|
+
name: proc.name,
|
|
554
|
+
pm_id: proc.pm_id,
|
|
555
|
+
exitCode
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
if (ndx === procs.length - 1) {
|
|
559
|
+
console.table(procsTable);
|
|
560
|
+
res(i)
|
|
561
|
+
}
|
|
562
|
+
})
|
|
563
|
+
})
|
|
564
|
+
}).then((failures: number) => {
|
|
565
|
+
console.log("Stopping PM2");
|
|
566
|
+
pm2.stop("all", (e) => console.error(e));
|
|
567
|
+
// pm2.killDaemon((e) => console.error(e));
|
|
568
|
+
pm2.disconnect();
|
|
569
|
+
|
|
570
|
+
console.log(`gracefully exiting with ${failures} failures`)
|
|
571
|
+
process.exit(failures);
|
|
572
|
+
})
|
|
519
573
|
}
|
|
520
574
|
|
|
521
575
|
private spinner() {
|
|
@@ -523,13 +577,25 @@ export class ITProject {
|
|
|
523
577
|
return this.spinAnimation[this.spinCycle];
|
|
524
578
|
}
|
|
525
579
|
|
|
526
|
-
private async
|
|
580
|
+
private async releaseTestResourceWs(payload: any) {
|
|
581
|
+
const name = payload.data.testResourceConfiguration.name;
|
|
582
|
+
const failed = payload.data.failed;
|
|
527
583
|
|
|
584
|
+
this.exitCodes[name] = failed;
|
|
585
|
+
|
|
586
|
+
Object.keys(this.ports).forEach((port: string) => {
|
|
587
|
+
if (this.ports[port] === name) {
|
|
588
|
+
this.ports[port] = OPEN_PORT;
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
private async releaseTestResourcePm2(payload: IAdios) {
|
|
528
594
|
const name = payload.testResourceConfiguration.name;
|
|
529
595
|
const failed = payload.failed;
|
|
530
|
-
console.log("releaseTestResources", name, failed)
|
|
531
596
|
|
|
532
|
-
|
|
597
|
+
this.exitCodes[name] = failed;
|
|
598
|
+
|
|
533
599
|
pm2.list((err, processes) => {
|
|
534
600
|
processes.forEach((proc: pm2.ProcessDescription) => {
|
|
535
601
|
if (proc.name === name) {
|
|
@@ -541,8 +607,6 @@ export class ITProject {
|
|
|
541
607
|
}
|
|
542
608
|
});
|
|
543
609
|
});
|
|
544
|
-
|
|
545
|
-
this.exitCodes[name] = failed;
|
|
546
610
|
}
|
|
547
611
|
|
|
548
612
|
private allocateViaWs(resourceRequest: {
|
|
@@ -550,109 +614,69 @@ export class ITProject {
|
|
|
550
614
|
protocol: ISchedulerProtocols;
|
|
551
615
|
}) {
|
|
552
616
|
|
|
553
|
-
const
|
|
617
|
+
const name = resourceRequest.requirement.name;
|
|
554
618
|
const testResourceRequirement = resourceRequest.requirement;
|
|
555
619
|
|
|
556
|
-
|
|
557
|
-
console.error(err);
|
|
558
|
-
processes.forEach((p) => {
|
|
559
|
-
if (p.name === pName && p.pid) {
|
|
560
|
-
const message = {
|
|
561
|
-
// these fields must be present
|
|
562
|
-
id: p.pid,
|
|
563
|
-
topic: "some topic",
|
|
564
|
-
type: "process:msg",
|
|
620
|
+
const websocket = this.websockets[name];
|
|
565
621
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
622
|
+
if (testResourceRequirement?.ports === 0) {
|
|
623
|
+
websocket.send(JSON.stringify({
|
|
624
|
+
data: {
|
|
625
|
+
testResourceConfiguration: {
|
|
626
|
+
ports: [],
|
|
627
|
+
},
|
|
628
|
+
}
|
|
629
|
+
}));
|
|
630
|
+
} else if ((testResourceRequirement?.ports || 0) > 0) {
|
|
631
|
+
// clear any port-slots associated with this job
|
|
632
|
+
Object.values(this.ports).forEach((jobMaybe, portNumber) => {
|
|
633
|
+
if (jobMaybe && jobMaybe === name) {
|
|
634
|
+
this.ports[portNumber] = OPEN_PORT;
|
|
635
|
+
}
|
|
636
|
+
});
|
|
575
637
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
638
|
+
// find a list of open ports
|
|
639
|
+
const foundOpenPorts = Object.keys(this.ports).filter(
|
|
640
|
+
(p) => this.ports[p] === OPEN_PORT
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
if (foundOpenPorts.length >= testResourceRequirement.ports) {
|
|
644
|
+
const selectionOfPorts = foundOpenPorts.slice(
|
|
645
|
+
0,
|
|
646
|
+
testResourceRequirement.ports
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
websocket.send(JSON.stringify({
|
|
650
|
+
data: {
|
|
651
|
+
testResourceConfiguration: {
|
|
652
|
+
ports: selectionOfPorts,
|
|
653
|
+
},
|
|
584
654
|
}
|
|
655
|
+
}));
|
|
585
656
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
if (jobMaybe && jobMaybe === pName) {
|
|
590
|
-
this.ports[portNumber] = OPEN_PORT;
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
// find a list of open ports
|
|
595
|
-
const foundOpenPorts = Object.keys(this.ports).filter(
|
|
596
|
-
(p) => this.ports[p] === OPEN_PORT
|
|
597
|
-
);
|
|
598
|
-
// if there are enough open port-slots...
|
|
599
|
-
if (foundOpenPorts.length >= testResourceRequirement.ports) {
|
|
600
|
-
const selectionOfPorts = foundOpenPorts.slice(
|
|
601
|
-
0,
|
|
602
|
-
testResourceRequirement.ports
|
|
603
|
-
);
|
|
604
|
-
|
|
605
|
-
const message = {
|
|
606
|
-
// these fields must be present
|
|
607
|
-
id: p.pid, // id of process from "pm2 list" command or from pm2.list(errback) method
|
|
608
|
-
topic: "some topic",
|
|
609
|
-
// process:msg will be send as 'message' on target process
|
|
610
|
-
type: "process:msg",
|
|
611
|
-
|
|
612
|
-
// Data to be sent
|
|
613
|
-
data: {
|
|
614
|
-
testResourceConfiguration: {
|
|
615
|
-
// fs: fPath,
|
|
616
|
-
ports: selectionOfPorts,
|
|
617
|
-
},
|
|
618
|
-
id: p.pid,
|
|
619
|
-
},
|
|
620
|
-
};
|
|
621
|
-
pm2.sendDataToProcessId(
|
|
622
|
-
p.pid,
|
|
623
|
-
message,
|
|
624
|
-
function (err, res) {
|
|
625
|
-
// no-op
|
|
626
|
-
}
|
|
627
|
-
);
|
|
628
|
-
// mark the selected ports as occupied
|
|
629
|
-
for (const foundOpenPort of selectionOfPorts) {
|
|
630
|
-
this.ports[foundOpenPort] = p.pid.toString();
|
|
631
|
-
}
|
|
632
|
-
} else {
|
|
633
|
-
console.log(
|
|
634
|
-
`no port was open so send the ${p.pid} job to the back of the resourceQueue`
|
|
635
|
-
);
|
|
636
|
-
this.resourceQueue.push(resourceRequest);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
657
|
+
// mark the selected ports as occupied
|
|
658
|
+
for (const foundOpenPort of selectionOfPorts) {
|
|
659
|
+
this.ports[foundOpenPort] = name;
|
|
639
660
|
}
|
|
640
|
-
}
|
|
641
|
-
|
|
661
|
+
} else {
|
|
662
|
+
console.log(
|
|
663
|
+
`no port was open so send the ${name} job to the back of the resourceQueue`
|
|
664
|
+
);
|
|
665
|
+
this.resourceQueue.push(resourceRequest);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
642
668
|
}
|
|
643
669
|
|
|
644
670
|
private allocateViaIpc(resourceRequest: {
|
|
645
671
|
requirement: ITTestResourceRequirement;
|
|
646
672
|
protocol: ISchedulerProtocols;
|
|
647
673
|
}) {
|
|
648
|
-
console.log("allocateViaIpc", resourceRequest)
|
|
649
674
|
const pName = resourceRequest.requirement.name;
|
|
650
675
|
const testResourceRequirement = resourceRequest.requirement;
|
|
651
676
|
|
|
652
677
|
pm2.list((err, processes) => {
|
|
653
678
|
console.error(err);
|
|
654
679
|
processes.forEach((p) => {
|
|
655
|
-
console.log("p.pid, p.name, p.pm_id", p.pid, p.name, p.pm_id);
|
|
656
680
|
if (p.name === pName && p.pid) {
|
|
657
681
|
const message = {
|
|
658
682
|
// these fields must be present
|
|
@@ -670,8 +694,6 @@ export class ITProject {
|
|
|
670
694
|
},
|
|
671
695
|
};
|
|
672
696
|
|
|
673
|
-
console.log("message", message);
|
|
674
|
-
|
|
675
697
|
if (testResourceRequirement?.ports === 0) {
|
|
676
698
|
pm2.sendDataToProcessId(
|
|
677
699
|
p.pm_id as number,
|
|
@@ -760,8 +782,7 @@ export class ITProject {
|
|
|
760
782
|
console.table(procsTable);
|
|
761
783
|
|
|
762
784
|
console.table(this.resourceQueue);
|
|
763
|
-
|
|
764
|
-
// console.log("resourceQueue", this.resourceQueue);
|
|
785
|
+
console.log("webSocketServer.clients", Object.keys(this.websockets));
|
|
765
786
|
|
|
766
787
|
const resourceRequest = this.resourceQueue.pop();
|
|
767
788
|
|
|
@@ -770,11 +791,18 @@ export class ITProject {
|
|
|
770
791
|
this.initiateShutdown("resource request queue is empty");
|
|
771
792
|
}
|
|
772
793
|
|
|
773
|
-
if (
|
|
794
|
+
if (
|
|
795
|
+
this.mode === "down" &&
|
|
796
|
+
(
|
|
797
|
+
procsTable.every(
|
|
798
|
+
(p) => p.pid === 0 || p.pid === undefined
|
|
799
|
+
) ||
|
|
800
|
+
procsTable.length === 0
|
|
801
|
+
)
|
|
802
|
+
) {
|
|
774
803
|
this.shutdown();
|
|
775
804
|
}
|
|
776
805
|
} else {
|
|
777
|
-
console.log("handling", resourceRequest);
|
|
778
806
|
if (resourceRequest.protocol === "ipc") {
|
|
779
807
|
this.allocateViaIpc(resourceRequest)
|
|
780
808
|
} else if (resourceRequest.protocol === "ws") {
|
|
@@ -796,16 +824,6 @@ export class ITProject {
|
|
|
796
824
|
console.log(this.spinner(), "Shutdown is in progress. Please wait.");
|
|
797
825
|
}
|
|
798
826
|
}
|
|
799
|
-
// console.log(this.spinner());
|
|
800
|
-
// console.log(
|
|
801
|
-
// this.spinner(),
|
|
802
|
-
// this.mode === `up`
|
|
803
|
-
// ? `press "q" to initiate graceful shutdown`
|
|
804
|
-
// : `please wait while testeranto shuts down gracefully...`
|
|
805
|
-
// );
|
|
806
827
|
});
|
|
807
|
-
|
|
808
|
-
|
|
809
828
|
};
|
|
810
|
-
|
|
811
829
|
}
|