@jsenv/test 3.1.0 → 3.2.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/dist/js/exception.js +5 -4
- package/dist/jsenv_test.js +115 -36
- package/package.json +4 -4
- package/src/execution/exception.js +5 -4
- package/src/execution/execute_test_plan.js +37 -32
- package/src/execution/format_error_for_terminal.js +1 -1
- package/src/execution/github_annotation_from_error.js +1 -1
- package/src/main.js +4 -0
- package/src/runtime_inline/runtime_inline.js +72 -0
package/dist/js/exception.js
CHANGED
|
@@ -809,6 +809,9 @@ const createException = (reason, { rootDirectoryUrl } = {}) => {
|
|
|
809
809
|
|
|
810
810
|
const stackFramesNonNative = [];
|
|
811
811
|
for (const stackFrame of stackFrames) {
|
|
812
|
+
if (!stackFrame.url) {
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
812
815
|
if (stackFrame.url.startsWith("node:")) {
|
|
813
816
|
stackFrame.native = "node";
|
|
814
817
|
continue;
|
|
@@ -907,9 +910,7 @@ const getErrorName = (value) => {
|
|
|
907
910
|
|
|
908
911
|
const getPropertiesFromEvalOrigin = (origin) => {
|
|
909
912
|
// Most eval() calls are in this format
|
|
910
|
-
const topLevelEvalMatch = /^eval at
|
|
911
|
-
origin,
|
|
912
|
-
);
|
|
913
|
+
const topLevelEvalMatch = /^eval at [^(]+ \(.+:\d+:\d+\)$/.exec(origin);
|
|
913
914
|
if (topLevelEvalMatch) {
|
|
914
915
|
const source = topLevelEvalMatch[2];
|
|
915
916
|
const line = Number(topLevelEvalMatch[3]);
|
|
@@ -921,7 +922,7 @@ const getPropertiesFromEvalOrigin = (origin) => {
|
|
|
921
922
|
};
|
|
922
923
|
}
|
|
923
924
|
// Parse nested eval() calls using recursion
|
|
924
|
-
const nestedEvalMatch = /^eval at
|
|
925
|
+
const nestedEvalMatch = /^eval at [^(]+ \(.+\)$/.exec(origin);
|
|
925
926
|
if (nestedEvalMatch) {
|
|
926
927
|
return getPropertiesFromEvalOrigin(nestedEvalMatch[2]);
|
|
927
928
|
}
|
package/dist/jsenv_test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os, { cpus, release, totalmem, availableParallelism, freemem } from "node:os";
|
|
2
2
|
import process$1, { cpuUsage, memoryUsage } from "node:process";
|
|
3
|
-
import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, unlinkSync, readdirSync, rmdirSync,
|
|
3
|
+
import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, readFileSync, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, unlinkSync, readdirSync, rmdirSync, existsSync } from "node:fs";
|
|
4
4
|
import { takeCoverage } from "node:v8";
|
|
5
5
|
import stripAnsi from "strip-ansi";
|
|
6
6
|
import { URL_META, createException } from "./js/exception.js";
|
|
@@ -2486,6 +2486,9 @@ const readFile = async (value, { as = "buffer" } = {}) => {
|
|
|
2486
2486
|
const writeFileSync = (destination, content = "") => {
|
|
2487
2487
|
const destinationUrl = assertAndNormalizeFileUrl(destination);
|
|
2488
2488
|
const destinationUrlObject = new URL(destinationUrl);
|
|
2489
|
+
if (content && content instanceof URL) {
|
|
2490
|
+
content = readFileSync(content);
|
|
2491
|
+
}
|
|
2489
2492
|
try {
|
|
2490
2493
|
writeFileSync$1(destinationUrlObject, content);
|
|
2491
2494
|
} catch (error) {
|
|
@@ -4295,7 +4298,7 @@ const stringifyUrlSite = ({ url, line, column }) => {
|
|
|
4295
4298
|
};
|
|
4296
4299
|
|
|
4297
4300
|
const replaceUrls$1 = (source, replace) => {
|
|
4298
|
-
return source.replace(/(?:https?|ftp|file):\/\/\S+/
|
|
4301
|
+
return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
|
|
4299
4302
|
let replacement = "";
|
|
4300
4303
|
const lastChar = match[match.length - 1];
|
|
4301
4304
|
|
|
@@ -4702,7 +4705,7 @@ const formatErrorForTerminal = (
|
|
|
4702
4705
|
// debugger
|
|
4703
4706
|
// })
|
|
4704
4707
|
const replaceUrls = (source, replace) => {
|
|
4705
|
-
return source.replace(/(?:https?|ftp|file):\/\/\S+/
|
|
4708
|
+
return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
|
|
4706
4709
|
let replacement = "";
|
|
4707
4710
|
const lastChar = match[match.length - 1];
|
|
4708
4711
|
|
|
@@ -6133,6 +6136,7 @@ To fix this warning:
|
|
|
6133
6136
|
runtime,
|
|
6134
6137
|
runtimeParams,
|
|
6135
6138
|
allocatedMs = defaultMsAllocatedPerExecution,
|
|
6139
|
+
uses,
|
|
6136
6140
|
} = stepConfig;
|
|
6137
6141
|
const params = {
|
|
6138
6142
|
measureMemoryUsage: true,
|
|
@@ -6140,6 +6144,7 @@ To fix this warning:
|
|
|
6140
6144
|
collectPerformance: false,
|
|
6141
6145
|
collectConsole: true,
|
|
6142
6146
|
allocatedMs,
|
|
6147
|
+
uses,
|
|
6143
6148
|
runtime,
|
|
6144
6149
|
runtimeParams: {
|
|
6145
6150
|
rootDirectoryUrl,
|
|
@@ -6169,6 +6174,7 @@ To fix this warning:
|
|
|
6169
6174
|
}
|
|
6170
6175
|
|
|
6171
6176
|
const execution = {
|
|
6177
|
+
name: `${relativeUrl}/${groupName}`,
|
|
6172
6178
|
counters,
|
|
6173
6179
|
countersInOrder,
|
|
6174
6180
|
index,
|
|
@@ -6321,7 +6327,13 @@ To fix this warning:
|
|
|
6321
6327
|
|
|
6322
6328
|
const executionRemainingSet = new Set(executionPlanifiedSet);
|
|
6323
6329
|
const executionExecutingSet = new Set();
|
|
6330
|
+
const usedTagSet = new Set();
|
|
6324
6331
|
const start = async (execution) => {
|
|
6332
|
+
if (execution.params.uses) {
|
|
6333
|
+
for (const tagThatWillBeUsed of execution.params.uses) {
|
|
6334
|
+
usedTagSet.add(tagThatWillBeUsed);
|
|
6335
|
+
}
|
|
6336
|
+
}
|
|
6325
6337
|
execution.fileExecutionCount = Object.keys(
|
|
6326
6338
|
testPlanResult.results[execution.fileRelativeUrl],
|
|
6327
6339
|
).length;
|
|
@@ -6341,7 +6353,6 @@ To fix this warning:
|
|
|
6341
6353
|
afterEachCallbackSet.add(callback);
|
|
6342
6354
|
}
|
|
6343
6355
|
}
|
|
6344
|
-
|
|
6345
6356
|
for (const beforeEachInOrderCallback of beforeEachInOrderCallbackSet) {
|
|
6346
6357
|
const returnValue = beforeEachInOrderCallback(
|
|
6347
6358
|
execution,
|
|
@@ -6374,7 +6385,6 @@ To fix this warning:
|
|
|
6374
6385
|
process.exitCode = 1;
|
|
6375
6386
|
}
|
|
6376
6387
|
}
|
|
6377
|
-
|
|
6378
6388
|
for (const afterEachCallback of afterEachCallbackSet) {
|
|
6379
6389
|
afterEachCallback(execution, testPlanResult);
|
|
6380
6390
|
}
|
|
@@ -6384,7 +6394,11 @@ To fix this warning:
|
|
|
6384
6394
|
afterEachInOrderCallback(execution, testPlanResult);
|
|
6385
6395
|
}
|
|
6386
6396
|
});
|
|
6387
|
-
|
|
6397
|
+
if (execution.params.uses) {
|
|
6398
|
+
for (const tagNoLongerInUse of execution.params.uses) {
|
|
6399
|
+
usedTagSet.delete(tagNoLongerInUse);
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6388
6402
|
if (testPlanResult.failed && failFast && counters.remaining) {
|
|
6389
6403
|
logger.info(`"failFast" enabled -> cancel remaining executions`);
|
|
6390
6404
|
failFastAbortController.abort();
|
|
@@ -6392,23 +6406,16 @@ To fix this warning:
|
|
|
6392
6406
|
}
|
|
6393
6407
|
};
|
|
6394
6408
|
const startAsMuchAsPossible = async () => {
|
|
6409
|
+
operation.throwIfAborted();
|
|
6395
6410
|
const promises = [];
|
|
6396
|
-
|
|
6397
|
-
while (true) {
|
|
6398
|
-
operation.throwIfAborted();
|
|
6399
|
-
if (executionRemainingSet.size === 0) {
|
|
6400
|
-
break;
|
|
6401
|
-
}
|
|
6411
|
+
for (const executionCandidate of executionRemainingSet) {
|
|
6402
6412
|
if (executionExecutingSet.size >= parallel.max) {
|
|
6403
6413
|
break;
|
|
6404
6414
|
}
|
|
6405
|
-
|
|
6406
|
-
if (
|
|
6415
|
+
if (executionExecutingSet.size > 0) {
|
|
6407
6416
|
// starting execution in parallel is limited by
|
|
6408
6417
|
// cpu and memory only when trying to parallelize
|
|
6409
6418
|
// if nothing is executing these limitations don't apply
|
|
6410
|
-
executionExecutingSet.size > 0
|
|
6411
|
-
) {
|
|
6412
6419
|
if (processMemoryUsageMonitoring.measure() > parallel.maxMemory) {
|
|
6413
6420
|
// retry after Xms in case memory usage decreases
|
|
6414
6421
|
const promise = (async () => {
|
|
@@ -6418,7 +6425,6 @@ To fix this warning:
|
|
|
6418
6425
|
promises.push(promise);
|
|
6419
6426
|
break;
|
|
6420
6427
|
}
|
|
6421
|
-
|
|
6422
6428
|
if (processCpuUsageMonitoring.measure() > parallel.maxCpu) {
|
|
6423
6429
|
// retry after Xms in case cpu usage decreases
|
|
6424
6430
|
const promise = (async () => {
|
|
@@ -6428,27 +6434,29 @@ To fix this warning:
|
|
|
6428
6434
|
promises.push(promise);
|
|
6429
6435
|
break;
|
|
6430
6436
|
}
|
|
6437
|
+
if (executionCandidate.params.uses) {
|
|
6438
|
+
const nonAvailableTag = executionCandidate.params.uses.find(
|
|
6439
|
+
(tagToUse) => usedTagSet.has(tagToUse),
|
|
6440
|
+
);
|
|
6441
|
+
if (nonAvailableTag) {
|
|
6442
|
+
logger.debug(
|
|
6443
|
+
`"${nonAvailableTag}" is not available, ${executionCandidate.name} will wait until it is released by a previous execution`,
|
|
6444
|
+
);
|
|
6445
|
+
continue;
|
|
6446
|
+
}
|
|
6447
|
+
}
|
|
6431
6448
|
}
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
execution = executionCandidate;
|
|
6438
|
-
break;
|
|
6439
|
-
}
|
|
6440
|
-
if (execution) {
|
|
6441
|
-
const promise = (async () => {
|
|
6442
|
-
await start(execution);
|
|
6443
|
-
await startAsMuchAsPossible();
|
|
6444
|
-
})();
|
|
6445
|
-
promises.push(promise);
|
|
6446
|
-
}
|
|
6449
|
+
const promise = (async () => {
|
|
6450
|
+
await start(executionCandidate);
|
|
6451
|
+
await startAsMuchAsPossible();
|
|
6452
|
+
})();
|
|
6453
|
+
promises.push(promise);
|
|
6447
6454
|
}
|
|
6448
|
-
if (promises.length) {
|
|
6449
|
-
|
|
6450
|
-
promises.length = 0;
|
|
6455
|
+
if (promises.length === 0) {
|
|
6456
|
+
return;
|
|
6451
6457
|
}
|
|
6458
|
+
await Promise.all(promises);
|
|
6459
|
+
promises.length = 0;
|
|
6452
6460
|
};
|
|
6453
6461
|
|
|
6454
6462
|
reporters = reporters.flat(Infinity);
|
|
@@ -9186,4 +9194,75 @@ const execute = async ({
|
|
|
9186
9194
|
}
|
|
9187
9195
|
};
|
|
9188
9196
|
|
|
9189
|
-
|
|
9197
|
+
const inlineRuntime = (fn) => {
|
|
9198
|
+
return {
|
|
9199
|
+
type: "inline",
|
|
9200
|
+
name: "inline",
|
|
9201
|
+
version: "1",
|
|
9202
|
+
run: async ({
|
|
9203
|
+
signal = new AbortController().signal,
|
|
9204
|
+
onRuntimeStarted,
|
|
9205
|
+
onRuntimeStopped,
|
|
9206
|
+
}) => {
|
|
9207
|
+
const actionOperation = Abort.startOperation();
|
|
9208
|
+
actionOperation.addAbortSignal(signal);
|
|
9209
|
+
const result = {
|
|
9210
|
+
status: "executing",
|
|
9211
|
+
errors: [],
|
|
9212
|
+
namespace: null,
|
|
9213
|
+
timings: {},
|
|
9214
|
+
memoryUsage: null,
|
|
9215
|
+
performance: null,
|
|
9216
|
+
};
|
|
9217
|
+
try {
|
|
9218
|
+
let executionInternalErrorCallback;
|
|
9219
|
+
let executionCompletedCallback;
|
|
9220
|
+
const winnerPromise = new Promise((resolve) => {
|
|
9221
|
+
raceCallbacks(
|
|
9222
|
+
{
|
|
9223
|
+
aborted: (cb) => {
|
|
9224
|
+
return actionOperation.addAbortCallback(cb);
|
|
9225
|
+
},
|
|
9226
|
+
execution_internal_error: (cb) => {
|
|
9227
|
+
executionInternalErrorCallback = cb;
|
|
9228
|
+
},
|
|
9229
|
+
execution_completed: (cb) => {
|
|
9230
|
+
executionCompletedCallback = cb;
|
|
9231
|
+
},
|
|
9232
|
+
},
|
|
9233
|
+
resolve,
|
|
9234
|
+
);
|
|
9235
|
+
});
|
|
9236
|
+
try {
|
|
9237
|
+
onRuntimeStarted();
|
|
9238
|
+
const value = await fn();
|
|
9239
|
+
executionCompletedCallback(value);
|
|
9240
|
+
} catch (e) {
|
|
9241
|
+
executionInternalErrorCallback(e);
|
|
9242
|
+
}
|
|
9243
|
+
const raceHandlers = {
|
|
9244
|
+
aborted: () => {
|
|
9245
|
+
result.status = "aborted";
|
|
9246
|
+
},
|
|
9247
|
+
execution_internal_error: (e) => {
|
|
9248
|
+
result.status = "failed";
|
|
9249
|
+
result.errors.push(e);
|
|
9250
|
+
},
|
|
9251
|
+
execution_completed: (value) => {
|
|
9252
|
+
result.status = "completed";
|
|
9253
|
+
result.errors = [];
|
|
9254
|
+
result.namespace = value;
|
|
9255
|
+
},
|
|
9256
|
+
};
|
|
9257
|
+
const winner = await winnerPromise;
|
|
9258
|
+
raceHandlers[winner.name](winner.data);
|
|
9259
|
+
} finally {
|
|
9260
|
+
onRuntimeStopped();
|
|
9261
|
+
await actionOperation.end();
|
|
9262
|
+
return result;
|
|
9263
|
+
}
|
|
9264
|
+
},
|
|
9265
|
+
};
|
|
9266
|
+
};
|
|
9267
|
+
|
|
9268
|
+
export { chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, inlineRuntime, nodeChildProcess, nodeWorkerThread, reportAsJunitXml, reportCoverageAsHtml, reportCoverageAsJson, reportCoverageInConsole, reporterList, webkit, webkitIsolatedTab };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/test",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@c88/v8-coverage": "0.1.1",
|
|
40
40
|
"@jsenv/abort": "4.3.0",
|
|
41
|
-
"@jsenv/ast": "6.1.
|
|
41
|
+
"@jsenv/ast": "6.1.1",
|
|
42
42
|
"@jsenv/filesystem": "4.7.2",
|
|
43
|
-
"@jsenv/github-check-run": "0.1.
|
|
43
|
+
"@jsenv/github-check-run": "0.1.17",
|
|
44
44
|
"@jsenv/humanize": "1.1.3",
|
|
45
|
-
"@jsenv/plugin-supervisor": "1.4.
|
|
45
|
+
"@jsenv/plugin-supervisor": "1.4.13",
|
|
46
46
|
"@jsenv/url-meta": "8.4.2",
|
|
47
47
|
"@jsenv/urls": "2.2.7",
|
|
48
48
|
"@jsenv/utils": "2.1.1",
|
|
@@ -110,6 +110,9 @@ export const createException = (reason, { rootDirectoryUrl } = {}) => {
|
|
|
110
110
|
|
|
111
111
|
const stackFramesNonNative = [];
|
|
112
112
|
for (const stackFrame of stackFrames) {
|
|
113
|
+
if (!stackFrame.url) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
113
116
|
if (stackFrame.url.startsWith("node:")) {
|
|
114
117
|
stackFrame.native = "node";
|
|
115
118
|
continue;
|
|
@@ -208,9 +211,7 @@ const getErrorName = (value) => {
|
|
|
208
211
|
|
|
209
212
|
const getPropertiesFromEvalOrigin = (origin) => {
|
|
210
213
|
// Most eval() calls are in this format
|
|
211
|
-
const topLevelEvalMatch = /^eval at
|
|
212
|
-
origin,
|
|
213
|
-
);
|
|
214
|
+
const topLevelEvalMatch = /^eval at [^(]+ \(.+:\d+:\d+\)$/.exec(origin);
|
|
214
215
|
if (topLevelEvalMatch) {
|
|
215
216
|
const source = topLevelEvalMatch[2];
|
|
216
217
|
const line = Number(topLevelEvalMatch[3]);
|
|
@@ -222,7 +223,7 @@ const getPropertiesFromEvalOrigin = (origin) => {
|
|
|
222
223
|
};
|
|
223
224
|
}
|
|
224
225
|
// Parse nested eval() calls using recursion
|
|
225
|
-
const nestedEvalMatch = /^eval at
|
|
226
|
+
const nestedEvalMatch = /^eval at [^(]+ \(.+\)$/.exec(origin);
|
|
226
227
|
if (nestedEvalMatch) {
|
|
227
228
|
return getPropertiesFromEvalOrigin(nestedEvalMatch[2]);
|
|
228
229
|
}
|
|
@@ -619,6 +619,7 @@ To fix this warning:
|
|
|
619
619
|
runtime,
|
|
620
620
|
runtimeParams,
|
|
621
621
|
allocatedMs = defaultMsAllocatedPerExecution,
|
|
622
|
+
uses,
|
|
622
623
|
} = stepConfig;
|
|
623
624
|
const params = {
|
|
624
625
|
measureMemoryUsage: true,
|
|
@@ -626,6 +627,7 @@ To fix this warning:
|
|
|
626
627
|
collectPerformance: false,
|
|
627
628
|
collectConsole: true,
|
|
628
629
|
allocatedMs,
|
|
630
|
+
uses,
|
|
629
631
|
runtime,
|
|
630
632
|
runtimeParams: {
|
|
631
633
|
rootDirectoryUrl,
|
|
@@ -655,6 +657,7 @@ To fix this warning:
|
|
|
655
657
|
}
|
|
656
658
|
|
|
657
659
|
const execution = {
|
|
660
|
+
name: `${relativeUrl}/${groupName}`,
|
|
658
661
|
counters,
|
|
659
662
|
countersInOrder,
|
|
660
663
|
index,
|
|
@@ -807,7 +810,13 @@ To fix this warning:
|
|
|
807
810
|
|
|
808
811
|
const executionRemainingSet = new Set(executionPlanifiedSet);
|
|
809
812
|
const executionExecutingSet = new Set();
|
|
813
|
+
const usedTagSet = new Set();
|
|
810
814
|
const start = async (execution) => {
|
|
815
|
+
if (execution.params.uses) {
|
|
816
|
+
for (const tagThatWillBeUsed of execution.params.uses) {
|
|
817
|
+
usedTagSet.add(tagThatWillBeUsed);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
811
820
|
execution.fileExecutionCount = Object.keys(
|
|
812
821
|
testPlanResult.results[execution.fileRelativeUrl],
|
|
813
822
|
).length;
|
|
@@ -827,7 +836,6 @@ To fix this warning:
|
|
|
827
836
|
afterEachCallbackSet.add(callback);
|
|
828
837
|
}
|
|
829
838
|
}
|
|
830
|
-
|
|
831
839
|
for (const beforeEachInOrderCallback of beforeEachInOrderCallbackSet) {
|
|
832
840
|
const returnValue = beforeEachInOrderCallback(
|
|
833
841
|
execution,
|
|
@@ -860,7 +868,6 @@ To fix this warning:
|
|
|
860
868
|
process.exitCode = 1;
|
|
861
869
|
}
|
|
862
870
|
}
|
|
863
|
-
|
|
864
871
|
for (const afterEachCallback of afterEachCallbackSet) {
|
|
865
872
|
afterEachCallback(execution, testPlanResult);
|
|
866
873
|
}
|
|
@@ -870,7 +877,11 @@ To fix this warning:
|
|
|
870
877
|
afterEachInOrderCallback(execution, testPlanResult);
|
|
871
878
|
}
|
|
872
879
|
});
|
|
873
|
-
|
|
880
|
+
if (execution.params.uses) {
|
|
881
|
+
for (const tagNoLongerInUse of execution.params.uses) {
|
|
882
|
+
usedTagSet.delete(tagNoLongerInUse);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
874
885
|
if (testPlanResult.failed && failFast && counters.remaining) {
|
|
875
886
|
logger.info(`"failFast" enabled -> cancel remaining executions`);
|
|
876
887
|
failFastAbortController.abort();
|
|
@@ -878,23 +889,16 @@ To fix this warning:
|
|
|
878
889
|
}
|
|
879
890
|
};
|
|
880
891
|
const startAsMuchAsPossible = async () => {
|
|
892
|
+
operation.throwIfAborted();
|
|
881
893
|
const promises = [];
|
|
882
|
-
|
|
883
|
-
while (true) {
|
|
884
|
-
operation.throwIfAborted();
|
|
885
|
-
if (executionRemainingSet.size === 0) {
|
|
886
|
-
break;
|
|
887
|
-
}
|
|
894
|
+
for (const executionCandidate of executionRemainingSet) {
|
|
888
895
|
if (executionExecutingSet.size >= parallel.max) {
|
|
889
896
|
break;
|
|
890
897
|
}
|
|
891
|
-
|
|
892
|
-
if (
|
|
898
|
+
if (executionExecutingSet.size > 0) {
|
|
893
899
|
// starting execution in parallel is limited by
|
|
894
900
|
// cpu and memory only when trying to parallelize
|
|
895
901
|
// if nothing is executing these limitations don't apply
|
|
896
|
-
executionExecutingSet.size > 0
|
|
897
|
-
) {
|
|
898
902
|
if (processMemoryUsageMonitoring.measure() > parallel.maxMemory) {
|
|
899
903
|
// retry after Xms in case memory usage decreases
|
|
900
904
|
const promise = (async () => {
|
|
@@ -904,7 +908,6 @@ To fix this warning:
|
|
|
904
908
|
promises.push(promise);
|
|
905
909
|
break;
|
|
906
910
|
}
|
|
907
|
-
|
|
908
911
|
if (processCpuUsageMonitoring.measure() > parallel.maxCpu) {
|
|
909
912
|
// retry after Xms in case cpu usage decreases
|
|
910
913
|
const promise = (async () => {
|
|
@@ -914,27 +917,29 @@ To fix this warning:
|
|
|
914
917
|
promises.push(promise);
|
|
915
918
|
break;
|
|
916
919
|
}
|
|
920
|
+
if (executionCandidate.params.uses) {
|
|
921
|
+
const nonAvailableTag = executionCandidate.params.uses.find(
|
|
922
|
+
(tagToUse) => usedTagSet.has(tagToUse),
|
|
923
|
+
);
|
|
924
|
+
if (nonAvailableTag) {
|
|
925
|
+
logger.debug(
|
|
926
|
+
`"${nonAvailableTag}" is not available, ${executionCandidate.name} will wait until it is released by a previous execution`,
|
|
927
|
+
);
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
917
931
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
execution = executionCandidate;
|
|
924
|
-
break;
|
|
925
|
-
}
|
|
926
|
-
if (execution) {
|
|
927
|
-
const promise = (async () => {
|
|
928
|
-
await start(execution);
|
|
929
|
-
await startAsMuchAsPossible();
|
|
930
|
-
})();
|
|
931
|
-
promises.push(promise);
|
|
932
|
-
}
|
|
932
|
+
const promise = (async () => {
|
|
933
|
+
await start(executionCandidate);
|
|
934
|
+
await startAsMuchAsPossible();
|
|
935
|
+
})();
|
|
936
|
+
promises.push(promise);
|
|
933
937
|
}
|
|
934
|
-
if (promises.length) {
|
|
935
|
-
|
|
936
|
-
promises.length = 0;
|
|
938
|
+
if (promises.length === 0) {
|
|
939
|
+
return;
|
|
937
940
|
}
|
|
941
|
+
await Promise.all(promises);
|
|
942
|
+
promises.length = 0;
|
|
938
943
|
};
|
|
939
944
|
|
|
940
945
|
reporters = reporters.flat(Infinity);
|
|
@@ -142,7 +142,7 @@ export const formatErrorForTerminal = (
|
|
|
142
142
|
// debugger
|
|
143
143
|
// })
|
|
144
144
|
const replaceUrls = (source, replace) => {
|
|
145
|
-
return source.replace(/(?:https?|ftp|file):\/\/\S+/
|
|
145
|
+
return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
|
|
146
146
|
let replacement = "";
|
|
147
147
|
const lastChar = match[match.length - 1];
|
|
148
148
|
|
|
@@ -85,7 +85,7 @@ const stringifyUrlSite = ({ url, line, column }) => {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
const replaceUrls = (source, replace) => {
|
|
88
|
-
return source.replace(/(?:https?|ftp|file):\/\/\S+/
|
|
88
|
+
return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
|
|
89
89
|
let replacement = "";
|
|
90
90
|
const lastChar = match[match.length - 1];
|
|
91
91
|
|
package/src/main.js
CHANGED
|
@@ -16,3 +16,7 @@ export { reporterList } from "./execution/reporters/reporter_list.js";
|
|
|
16
16
|
export { reportAsJunitXml } from "./execution/junit_xml_file/report_as_junit_xml.js";
|
|
17
17
|
// advanced
|
|
18
18
|
export { execute } from "./execution/execute.js";
|
|
19
|
+
|
|
20
|
+
// internals
|
|
21
|
+
// help for internal self unit test
|
|
22
|
+
export { inlineRuntime } from "./runtime_inline/runtime_inline.js";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Abort, raceCallbacks } from "@jsenv/abort";
|
|
2
|
+
|
|
3
|
+
export const inlineRuntime = (fn) => {
|
|
4
|
+
return {
|
|
5
|
+
type: "inline",
|
|
6
|
+
name: "inline",
|
|
7
|
+
version: "1",
|
|
8
|
+
run: async ({
|
|
9
|
+
signal = new AbortController().signal,
|
|
10
|
+
onRuntimeStarted,
|
|
11
|
+
onRuntimeStopped,
|
|
12
|
+
}) => {
|
|
13
|
+
const actionOperation = Abort.startOperation();
|
|
14
|
+
actionOperation.addAbortSignal(signal);
|
|
15
|
+
const result = {
|
|
16
|
+
status: "executing",
|
|
17
|
+
errors: [],
|
|
18
|
+
namespace: null,
|
|
19
|
+
timings: {},
|
|
20
|
+
memoryUsage: null,
|
|
21
|
+
performance: null,
|
|
22
|
+
};
|
|
23
|
+
try {
|
|
24
|
+
let executionInternalErrorCallback;
|
|
25
|
+
let executionCompletedCallback;
|
|
26
|
+
const winnerPromise = new Promise((resolve) => {
|
|
27
|
+
raceCallbacks(
|
|
28
|
+
{
|
|
29
|
+
aborted: (cb) => {
|
|
30
|
+
return actionOperation.addAbortCallback(cb);
|
|
31
|
+
},
|
|
32
|
+
execution_internal_error: (cb) => {
|
|
33
|
+
executionInternalErrorCallback = cb;
|
|
34
|
+
},
|
|
35
|
+
execution_completed: (cb) => {
|
|
36
|
+
executionCompletedCallback = cb;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
resolve,
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
try {
|
|
43
|
+
onRuntimeStarted();
|
|
44
|
+
const value = await fn();
|
|
45
|
+
executionCompletedCallback(value);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
executionInternalErrorCallback(e);
|
|
48
|
+
}
|
|
49
|
+
const raceHandlers = {
|
|
50
|
+
aborted: () => {
|
|
51
|
+
result.status = "aborted";
|
|
52
|
+
},
|
|
53
|
+
execution_internal_error: (e) => {
|
|
54
|
+
result.status = "failed";
|
|
55
|
+
result.errors.push(e);
|
|
56
|
+
},
|
|
57
|
+
execution_completed: (value) => {
|
|
58
|
+
result.status = "completed";
|
|
59
|
+
result.errors = [];
|
|
60
|
+
result.namespace = value;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const winner = await winnerPromise;
|
|
64
|
+
raceHandlers[winner.name](winner.data);
|
|
65
|
+
} finally {
|
|
66
|
+
onRuntimeStopped();
|
|
67
|
+
await actionOperation.end();
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
};
|