@codyswann/lisa 4.28.5 → 4.29.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/all/copy-overwrite/scripts/lisa-gates.mjs +2 -1
- package/all/copy-overwrite/scripts/lisa-hooks/sonar-secrets.sh +3 -2
- package/cdk/create-only/vitest.config.local.ts +5 -1
- package/cdk/package-lisa/package.lisa.json +14 -7
- package/dist/cli/lisa-test-run-bootstrap.d.ts +3 -0
- package/dist/cli/lisa-test-run-bootstrap.d.ts.map +1 -0
- package/dist/cli/lisa-test-run-bootstrap.js +201 -0
- package/dist/cli/lisa-test-run-bootstrap.js.map +1 -0
- package/dist/cli/lisa-test-run-ipc.d.ts +42 -0
- package/dist/cli/lisa-test-run-ipc.d.ts.map +1 -0
- package/dist/cli/lisa-test-run-ipc.js +200 -0
- package/dist/cli/lisa-test-run-ipc.js.map +1 -0
- package/dist/cli/lisa-test-run-process-group.d.ts +30 -0
- package/dist/cli/lisa-test-run-process-group.d.ts.map +1 -0
- package/dist/cli/lisa-test-run-process-group.js +123 -0
- package/dist/cli/lisa-test-run-process-group.js.map +1 -0
- package/dist/cli/lisa-test-run-reaper.d.ts +3 -0
- package/dist/cli/lisa-test-run-reaper.d.ts.map +1 -0
- package/dist/cli/lisa-test-run-reaper.js +195 -0
- package/dist/cli/lisa-test-run-reaper.js.map +1 -0
- package/dist/cli/lisa-test-run-runtime.d.ts +46 -0
- package/dist/cli/lisa-test-run-runtime.d.ts.map +1 -0
- package/dist/cli/lisa-test-run-runtime.js +123 -0
- package/dist/cli/lisa-test-run-runtime.js.map +1 -0
- package/dist/cli/lisa-test-run-supervisor.d.ts +13 -0
- package/dist/cli/lisa-test-run-supervisor.d.ts.map +1 -0
- package/dist/cli/lisa-test-run-supervisor.js +268 -0
- package/dist/cli/lisa-test-run-supervisor.js.map +1 -0
- package/dist/cli/lisa-test-run.d.ts +3 -0
- package/dist/cli/lisa-test-run.d.ts.map +1 -0
- package/dist/cli/lisa-test-run.js +66 -0
- package/dist/cli/lisa-test-run.js.map +1 -0
- package/dist/configs/vitest/base.d.ts.map +1 -1
- package/dist/configs/vitest/base.js +5 -2
- package/dist/configs/vitest/base.js.map +1 -1
- package/dist/configs/vitest/cdk.d.ts +4 -0
- package/dist/configs/vitest/cdk.d.ts.map +1 -1
- package/dist/configs/vitest/cdk.js +5 -0
- package/dist/configs/vitest/cdk.js.map +1 -1
- package/dist/configs/vitest/harper-fabric.d.ts.map +1 -1
- package/dist/configs/vitest/harper-fabric.js +1 -0
- package/dist/configs/vitest/harper-fabric.js.map +1 -1
- package/dist/configs/vitest/nestjs.d.ts.map +1 -1
- package/dist/configs/vitest/nestjs.js +1 -0
- package/dist/configs/vitest/nestjs.js.map +1 -1
- package/dist/configs/vitest/phaser.d.ts.map +1 -1
- package/dist/configs/vitest/phaser.js +1 -0
- package/dist/configs/vitest/phaser.js.map +1 -1
- package/dist/configs/vitest/scratch-authority.d.ts +25 -0
- package/dist/configs/vitest/scratch-authority.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-authority.js +107 -0
- package/dist/configs/vitest/scratch-authority.js.map +1 -0
- package/dist/configs/vitest/scratch-bound-cleanup-programs.d.ts +5 -0
- package/dist/configs/vitest/scratch-bound-cleanup-programs.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-bound-cleanup-programs.js +219 -0
- package/dist/configs/vitest/scratch-bound-cleanup-programs.js.map +1 -0
- package/dist/configs/vitest/scratch-bound-cleanup.d.ts +28 -0
- package/dist/configs/vitest/scratch-bound-cleanup.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-bound-cleanup.js +155 -0
- package/dist/configs/vitest/scratch-bound-cleanup.js.map +1 -0
- package/dist/configs/vitest/scratch-bound-root-cleanup.d.ts +17 -0
- package/dist/configs/vitest/scratch-bound-root-cleanup.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-bound-root-cleanup.js +149 -0
- package/dist/configs/vitest/scratch-bound-root-cleanup.js.map +1 -0
- package/dist/configs/vitest/scratch-global-setup.d.ts +17 -9
- package/dist/configs/vitest/scratch-global-setup.d.ts.map +1 -1
- package/dist/configs/vitest/scratch-global-setup.js +103 -35
- package/dist/configs/vitest/scratch-global-setup.js.map +1 -1
- package/dist/configs/vitest/scratch-leak-setup.d.ts +2 -0
- package/dist/configs/vitest/scratch-leak-setup.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-leak-setup.js +108 -0
- package/dist/configs/vitest/scratch-leak-setup.js.map +1 -0
- package/dist/configs/vitest/scratch-namespace-authority.d.ts +80 -0
- package/dist/configs/vitest/scratch-namespace-authority.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-namespace-authority.js +291 -0
- package/dist/configs/vitest/scratch-namespace-authority.js.map +1 -0
- package/dist/configs/vitest/scratch-owner.d.ts +131 -0
- package/dist/configs/vitest/scratch-owner.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-owner.js +297 -0
- package/dist/configs/vitest/scratch-owner.js.map +1 -0
- package/dist/configs/vitest/scratch-route-profile.d.ts +36 -0
- package/dist/configs/vitest/scratch-route-profile.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-route-profile.js +217 -0
- package/dist/configs/vitest/scratch-route-profile.js.map +1 -0
- package/dist/configs/vitest/scratch-run-root-compatibility.d.ts +33 -0
- package/dist/configs/vitest/scratch-run-root-compatibility.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-run-root-compatibility.js +137 -0
- package/dist/configs/vitest/scratch-run-root-compatibility.js.map +1 -0
- package/dist/configs/vitest/scratch-run-root-intent.d.ts +66 -0
- package/dist/configs/vitest/scratch-run-root-intent.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-run-root-intent.js +183 -0
- package/dist/configs/vitest/scratch-run-root-intent.js.map +1 -0
- package/dist/configs/vitest/scratch-setup.d.ts.map +1 -1
- package/dist/configs/vitest/scratch-setup.js +45 -15
- package/dist/configs/vitest/scratch-setup.js.map +1 -1
- package/dist/configs/vitest/scratch-supervision-intent.d.ts +8 -0
- package/dist/configs/vitest/scratch-supervision-intent.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-supervision-intent.js +125 -0
- package/dist/configs/vitest/scratch-supervision-intent.js.map +1 -0
- package/dist/configs/vitest/scratch-supervision-protocol.d.ts +12 -0
- package/dist/configs/vitest/scratch-supervision-protocol.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-supervision-protocol.js +230 -0
- package/dist/configs/vitest/scratch-supervision-protocol.js.map +1 -0
- package/dist/configs/vitest/scratch-supervision.d.ts +64 -0
- package/dist/configs/vitest/scratch-supervision.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-supervision.js +209 -0
- package/dist/configs/vitest/scratch-supervision.js.map +1 -0
- package/dist/configs/vitest/scratch-sweep.d.ts +66 -0
- package/dist/configs/vitest/scratch-sweep.d.ts.map +1 -0
- package/dist/configs/vitest/scratch-sweep.js +82 -0
- package/dist/configs/vitest/scratch-sweep.js.map +1 -0
- package/dist/configs/vitest/scratch.d.ts +14 -187
- package/dist/configs/vitest/scratch.d.ts.map +1 -1
- package/dist/configs/vitest/scratch.js +18 -285
- package/dist/configs/vitest/scratch.js.map +1 -1
- package/dist/configs/vitest/typescript.d.ts.map +1 -1
- package/dist/configs/vitest/typescript.js +1 -0
- package/dist/configs/vitest/typescript.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +4 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +59 -13
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/package-lisa/package.lisa.json +14 -14
- package/harper-fabric/package-lisa/package.lisa.json +8 -3
- package/nestjs/create-only/vitest.config.local.ts +5 -1
- package/nestjs/package-lisa/package.lisa.json +14 -8
- package/npm-package/package-lisa/package.lisa.json +8 -0
- package/package.json +17 -13
- package/phaser/package-lisa/package.lisa.json +9 -3
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/sonar-secrets.sh +3 -2
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/sonar-secrets.sh +3 -2
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/sonar-secrets.sh +3 -2
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/sonar-secrets.sh +3 -2
- package/typescript/create-only/vitest.config.local.ts +5 -1
- package/typescript/package-lisa/package.lisa.json +14 -8
|
@@ -1523,7 +1523,8 @@ const QUALITY_FALLBACKS = Object.freeze({
|
|
|
1523
1523
|
],
|
|
1524
1524
|
},
|
|
1525
1525
|
test_node_suites: {
|
|
1526
|
-
command:
|
|
1526
|
+
command:
|
|
1527
|
+
"lisa-test-run --profile <stack-or-node> --adapter direct -- node <lisa>/scripts/lisa-test-node.mjs",
|
|
1527
1528
|
seedRun: ["test:node"],
|
|
1528
1529
|
steps: ["🧪 Run .mjs suites (lisa-test-node)"],
|
|
1529
1530
|
},
|
|
@@ -137,10 +137,11 @@ is_inactive() {
|
|
|
137
137
|
# The FIFO is a rendezvous, not storage: a named pipe holds no data at rest, so
|
|
138
138
|
# the value still never lands on disk (CWE-922) and a kill at any point leaves an
|
|
139
139
|
# empty pipe behind rather than a readable token. The directory is `mktemp -d`,
|
|
140
|
-
# which is 0700.
|
|
140
|
+
# which is 0700. Its explicit Lisa prefix makes an interrupted resolver
|
|
141
|
+
# attributable to the owning scratch lifecycle instead of anonymous `tmp.*`.
|
|
141
142
|
resolve_secret() {
|
|
142
143
|
local resolver="$1" name="$2" value="" child="" dir="" fifo=""
|
|
143
|
-
dir="$(mktemp -d)" || return 0
|
|
144
|
+
dir="$(mktemp -d "${TMPDIR:-/tmp}/lisa-sonar-resolver.XXXXXXXX")" || return 0
|
|
144
145
|
fifo="$dir/resolver"
|
|
145
146
|
if ! mkfifo -m 600 "$fifo" 2>/dev/null; then
|
|
146
147
|
rm -rf "$dir"
|
|
@@ -28,7 +28,11 @@
|
|
|
28
28
|
import type { ViteUserConfig } from "vitest/config";
|
|
29
29
|
|
|
30
30
|
const config: ViteUserConfig = {
|
|
31
|
-
|
|
31
|
+
test: {
|
|
32
|
+
// Scratch redirection must install before the leak guard, and the guard's
|
|
33
|
+
// afterAll must run after project hooks so cleanup is attributed correctly.
|
|
34
|
+
sequence: { setupFiles: "list", hooks: "stack" },
|
|
35
|
+
},
|
|
32
36
|
};
|
|
33
37
|
|
|
34
38
|
export default config;
|
|
@@ -6,15 +6,16 @@
|
|
|
6
6
|
"cdk": "cdk",
|
|
7
7
|
"build": "tsc --noEmit",
|
|
8
8
|
"prepare": "husky install || true",
|
|
9
|
-
"test": "vitest run",
|
|
10
|
-
"test:unit": "vitest run --exclude='**/integration/**'",
|
|
11
|
-
"test:integration:lisa": "vitest run '.integration.' 'integration/'",
|
|
12
|
-
"test:cov": "vitest run --coverage",
|
|
13
|
-
"test:
|
|
14
|
-
"test:
|
|
9
|
+
"test": "lisa-test-run --profile cdk --adapter vitest -- vitest run",
|
|
10
|
+
"test:unit": "lisa-test-run --profile cdk --adapter vitest -- vitest run --exclude='**/integration/**'",
|
|
11
|
+
"test:integration:lisa": "lisa-test-run --profile cdk --adapter vitest -- vitest run '.integration.' 'integration/'",
|
|
12
|
+
"test:cov": "lisa-test-run --profile cdk --adapter vitest -- vitest run --coverage",
|
|
13
|
+
"test:cov:unit": "LISA_COVERAGE_SCOPE=unit lisa-test-run --profile cdk --adapter vitest -- vitest run --coverage --exclude='**/integration/**'",
|
|
14
|
+
"test:mutation": "LISA_TEST_SCRATCH_PREFIXES='[\"lisa-mutation-\",\"worker-\"]' lisa-test-run --profile cdk --adapter direct -- node scripts/lisa-mutation.mjs",
|
|
15
|
+
"test:watch": "lisa-test-run --profile cdk --adapter vitest -- vitest",
|
|
15
16
|
"lint:lisa": "oxlint && eslint . --quiet",
|
|
16
17
|
"lint:fix": "oxlint --fix && eslint . --fix",
|
|
17
|
-
"test:node": "node scripts/lisa-test-node.mjs"
|
|
18
|
+
"test:node": "LISA_TEST_SCRATCH_PREFIXES='[\"node-\"]' lisa-test-run --profile cdk --adapter direct -- node scripts/lisa-test-node.mjs"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"aws-cdk-github-oidc": "^2.4.1",
|
|
@@ -68,6 +69,12 @@
|
|
|
68
69
|
"adopt": {
|
|
69
70
|
"scripts": {
|
|
70
71
|
"test:integration": [
|
|
72
|
+
"lisa-test-run --profile cdk --adapter vitest -- vitest run '.integration.' 'integration/' --passWithNoTests",
|
|
73
|
+
"lisa-test-run --profile cdk --adapter vitest -- vitest run '.integration.' 'integration/'",
|
|
74
|
+
"lisa-test-run --profile cdk -- vitest run '.integration.' 'integration/' --passWithNoTests",
|
|
75
|
+
"lisa-test-run --profile cdk -- vitest run '.integration.' 'integration/'",
|
|
76
|
+
"lisa-test-run -- vitest run '.integration.' 'integration/' --passWithNoTests",
|
|
77
|
+
"lisa-test-run -- vitest run '.integration.' 'integration/'",
|
|
71
78
|
"vitest run '.integration.' 'integration/' --passWithNoTests",
|
|
72
79
|
"vitest run '.integration.' 'integration/'",
|
|
73
80
|
"vitest run tests/integration",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lisa-test-run-bootstrap.d.ts","sourceRoot":"","sources":["../../src/cli/lisa-test-run-bootstrap.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** Inert process-group leader that gates a supervised test payload on GO. */
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { env } from "node:process";
|
|
5
|
+
import { parseScratchProtocolMessage } from "../configs/vitest/scratch-supervision.js";
|
|
6
|
+
/** Private deterministic IPC-close seam, never inherited by the payload. */
|
|
7
|
+
const TEST_FAULT_ENV = "LISA_TEST_RUN_TEST_FAULT";
|
|
8
|
+
/** Signals the foreground supervisor owns and the group leader must survive. */
|
|
9
|
+
const SUPERVISED_SIGNALS = [
|
|
10
|
+
"SIGINT",
|
|
11
|
+
"SIGTERM",
|
|
12
|
+
"SIGHUP",
|
|
13
|
+
];
|
|
14
|
+
/**
|
|
15
|
+
* Parse the exact bounded inert command envelope.
|
|
16
|
+
* @param value - Parsed IPC command body
|
|
17
|
+
* @returns Validated command
|
|
18
|
+
*/
|
|
19
|
+
function validateCommand(value) {
|
|
20
|
+
const candidate = value;
|
|
21
|
+
if (typeof value !== "object" ||
|
|
22
|
+
value === null ||
|
|
23
|
+
candidate.schema !== 1 ||
|
|
24
|
+
!Array.isArray(candidate.argv) ||
|
|
25
|
+
candidate.argv.length === 0 ||
|
|
26
|
+
!candidate.argv.every(argument => typeof argument === "string") ||
|
|
27
|
+
typeof candidate.env !== "object" ||
|
|
28
|
+
candidate.env === null ||
|
|
29
|
+
!Object.values(candidate.env).every(entry => typeof entry === "string")) {
|
|
30
|
+
throw new Error("Invalid lisa-test-run bootstrap command schema");
|
|
31
|
+
}
|
|
32
|
+
return candidate;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Forward one signal to the payload when it is still present.
|
|
36
|
+
* @param payload - Current payload process
|
|
37
|
+
* @param signal - Signal to deliver
|
|
38
|
+
*/
|
|
39
|
+
function signalPayload(payload, signal) {
|
|
40
|
+
try {
|
|
41
|
+
payload?.kill(signal);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// A concurrently exiting payload is already drained.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Kill the payload and mark operational failure after channel loss.
|
|
49
|
+
* @param state - Bootstrap lifecycle state
|
|
50
|
+
*/
|
|
51
|
+
function failClosed(state) {
|
|
52
|
+
if (state.failingClosed)
|
|
53
|
+
return;
|
|
54
|
+
// eslint-disable-next-line functional/immutable-data -- one-process protocol state transition
|
|
55
|
+
state.failingClosed = true;
|
|
56
|
+
if (!state.payloadExited)
|
|
57
|
+
signalPayload(state.payload, "SIGKILL");
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
if (process.connected)
|
|
60
|
+
process.disconnect();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Send one exact response with callback-safe channel settlement.
|
|
64
|
+
* @param state - Bootstrap lifecycle state
|
|
65
|
+
* @param message - Exact protocol response
|
|
66
|
+
*/
|
|
67
|
+
function sendResponse(state, message) {
|
|
68
|
+
const type = message["type"];
|
|
69
|
+
const fault = env[TEST_FAULT_ENV];
|
|
70
|
+
const closeForFault = (fault === "bootstrap-close-command-ready" && type === "COMMAND_READY") ||
|
|
71
|
+
(fault === "bootstrap-close-payload-exit" && type === "PAYLOAD_EXIT");
|
|
72
|
+
if (closeForFault && process.connected)
|
|
73
|
+
process.disconnect();
|
|
74
|
+
if (!process.connected || process.send === undefined) {
|
|
75
|
+
failClosed(state);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
process.send(message, error => {
|
|
80
|
+
if (error !== null)
|
|
81
|
+
failClosed(state);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
failClosed(state);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Start one payload only after the ordered COMMAND/GO handshake.
|
|
90
|
+
* @param state - Bootstrap lifecycle state
|
|
91
|
+
* @param command - Immutable payload command
|
|
92
|
+
*/
|
|
93
|
+
function startPayload(state, command) {
|
|
94
|
+
// eslint-disable-next-line functional/immutable-data -- ordered protocol transition before spawn
|
|
95
|
+
state.phase = "running";
|
|
96
|
+
const payload = spawn(command.argv[0], command.argv.slice(1), {
|
|
97
|
+
cwd: process.cwd(),
|
|
98
|
+
env: command.env,
|
|
99
|
+
detached: false,
|
|
100
|
+
shell: false,
|
|
101
|
+
stdio: "inherit",
|
|
102
|
+
});
|
|
103
|
+
// eslint-disable-next-line functional/immutable-data -- single owned payload handle
|
|
104
|
+
state.payload = payload;
|
|
105
|
+
payload.once("error", error => {
|
|
106
|
+
sendResponse(state, {
|
|
107
|
+
schema: 1,
|
|
108
|
+
type: "PAYLOAD_ERROR",
|
|
109
|
+
message: error.message,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
payload.once("exit", (code, signal) => {
|
|
113
|
+
// eslint-disable-next-line functional/immutable-data -- terminal payload state
|
|
114
|
+
state.payloadExited = true;
|
|
115
|
+
// eslint-disable-next-line functional/immutable-data -- terminal payload state
|
|
116
|
+
state.phase = "payload-exited";
|
|
117
|
+
sendResponse(state, { schema: 1, type: "PAYLOAD_EXIT", code, signal });
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Deliver a forwarded signal, treating one outside `running` as the race it is.
|
|
122
|
+
*
|
|
123
|
+
* Two windows produce a legitimate out-of-phase SIGNAL: the supervisor arms its
|
|
124
|
+
* handlers before it sends GO, so a signal there arrives in `await-go`; and the
|
|
125
|
+
* payload's own exit records `payload-exited` before PAYLOAD_EXIT reaches the
|
|
126
|
+
* supervisor, so a signal forwarded in that gap arrives after there is anything
|
|
127
|
+
* left to signal. Refusing either would fail this process closed -- exit 1 and
|
|
128
|
+
* an abrupt disconnect -- reporting an ordinary signal-terminated run as a
|
|
129
|
+
* protocol refusal plus an unexpected channel loss.
|
|
130
|
+
* @param state - Bootstrap lifecycle state
|
|
131
|
+
* @param signal - Signal the supervisor forwarded
|
|
132
|
+
*/
|
|
133
|
+
function forwardSignal(state, signal) {
|
|
134
|
+
if (state.phase !== "running")
|
|
135
|
+
return;
|
|
136
|
+
signalPayload(state.payload, signal);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Apply one already-validated message to the exact protocol phase.
|
|
140
|
+
* @param state - Bootstrap lifecycle state
|
|
141
|
+
* @param message - Untrusted IPC message
|
|
142
|
+
*/
|
|
143
|
+
function handleMessage(state, message) {
|
|
144
|
+
const protocol = parseScratchProtocolMessage(message);
|
|
145
|
+
const type = protocol.type;
|
|
146
|
+
if (state.phase === "await-command" && type === "COMMAND") {
|
|
147
|
+
// eslint-disable-next-line functional/immutable-data -- command becomes immutable after the one accepted transition
|
|
148
|
+
state.command = validateCommand(protocol["command"]);
|
|
149
|
+
// eslint-disable-next-line functional/immutable-data -- ordered protocol transition
|
|
150
|
+
state.phase = "await-go";
|
|
151
|
+
sendResponse(state, { schema: 1, type: "COMMAND_READY" });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (state.phase === "await-go" && type === "GO" && state.command) {
|
|
155
|
+
startPayload(state, state.command);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (type === "SIGNAL") {
|
|
159
|
+
forwardSignal(state, protocol["signal"]);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (type === "STOP" && state.phase !== "stopping") {
|
|
163
|
+
// eslint-disable-next-line functional/immutable-data -- terminal protocol transition
|
|
164
|
+
state.phase = "stopping";
|
|
165
|
+
if (!state.payloadExited)
|
|
166
|
+
signalPayload(state.payload, "SIGKILL");
|
|
167
|
+
process.disconnect();
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`Unexpected ${type} in bootstrap state ${state.phase}`);
|
|
171
|
+
}
|
|
172
|
+
/** Run the process-group leader protocol. */
|
|
173
|
+
function main() {
|
|
174
|
+
const state = {
|
|
175
|
+
payloadExited: false,
|
|
176
|
+
failingClosed: false,
|
|
177
|
+
phase: "await-command",
|
|
178
|
+
};
|
|
179
|
+
for (const signal of SUPERVISED_SIGNALS) {
|
|
180
|
+
process.on(signal, () => undefined);
|
|
181
|
+
}
|
|
182
|
+
sendResponse(state, { schema: 1, type: "BOOTSTRAP_READY", pid: process.pid });
|
|
183
|
+
process.on("message", message => {
|
|
184
|
+
try {
|
|
185
|
+
handleMessage(state, message);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
process.stderr.write(`lisa-test-run bootstrap refused protocol: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
189
|
+
failClosed(state);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
process.on("disconnect", () => failClosed(state));
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
main();
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
process.stderr.write(`lisa-test-run bootstrap failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=lisa-test-run-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lisa-test-run-bootstrap.js","sourceRoot":"","sources":["../../src/cli/lisa-test-run-bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Exact, bounded parent-side IPC operations for lisa-test-run companions. */
|
|
2
|
+
import type { ChildProcess } from "node:child_process";
|
|
3
|
+
import { type ScratchProtocolMessageV1 } from "../configs/vitest/scratch-supervision.js";
|
|
4
|
+
/** Child outcome retained until cleanup and disarm are proven. */
|
|
5
|
+
export interface PayloadOutcome {
|
|
6
|
+
readonly code: number | null;
|
|
7
|
+
readonly signal: NodeJS.Signals | null;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Wait for one exact child acknowledgement or fail closed.
|
|
11
|
+
* @param child - Protocol companion
|
|
12
|
+
* @param expected - Exact expected type
|
|
13
|
+
* @param correlation - Optional exact root token
|
|
14
|
+
* @returns Promise settled by the exact validated acknowledgement
|
|
15
|
+
*/
|
|
16
|
+
export declare function waitForMessage(child: ChildProcess, expected: string, correlation?: string): Promise<ScratchProtocolMessageV1>;
|
|
17
|
+
/**
|
|
18
|
+
* Wait until a protocol companion is absent from the process table.
|
|
19
|
+
* @param child - Protocol companion
|
|
20
|
+
* @returns Promise settled after exit
|
|
21
|
+
*/
|
|
22
|
+
export declare function waitForExit(child: ChildProcess): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Send one versioned message or reject a closed IPC channel.
|
|
25
|
+
* @param child - Protocol companion
|
|
26
|
+
* @param message - Exact message body without schema
|
|
27
|
+
* @returns Callback-settled send promise
|
|
28
|
+
*/
|
|
29
|
+
export declare function sendMessage(child: ChildProcess, message: Readonly<Record<string, unknown>>): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Wait for the payload result and reject every other message.
|
|
32
|
+
* @param bootstrap - Inert bootstrap leader
|
|
33
|
+
* @param signalEscalating - Whether parent signal escalation owns its exit
|
|
34
|
+
* @returns Exact payload result
|
|
35
|
+
*/
|
|
36
|
+
export declare function waitForPayload(bootstrap: ChildProcess, signalEscalating?: () => boolean): Promise<PayloadOutcome>;
|
|
37
|
+
/**
|
|
38
|
+
* Stop the inert leader and wait for it to leave the target group.
|
|
39
|
+
* @param bootstrap - Inert bootstrap leader
|
|
40
|
+
*/
|
|
41
|
+
export declare function stopBootstrap(bootstrap: ChildProcess): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=lisa-test-run-ipc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lisa-test-run-ipc.d.ts","sourceRoot":"","sources":["../../src/cli/lisa-test-run-ipc.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,0CAA0C,CAAC;AAgDlD,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;CACxC;AAOD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,wBAAwB,CAAC,CAsCnC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,YAAY,EACvB,gBAAgB,GAAE,MAAM,OAAqB,GAC5C,OAAO,CAAC,cAAc,CAAC,CAkCzB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAa1E"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { once } from "node:events";
|
|
2
|
+
import { env } from "node:process";
|
|
3
|
+
import { parseScratchProtocolMessage, } from "../configs/vitest/scratch-supervision.js";
|
|
4
|
+
/** Protocol timeout for one inert local acknowledgement. */
|
|
5
|
+
const ACK_TIMEOUT_MS = 10_000;
|
|
6
|
+
/** Private deterministic protocol-fault seam. */
|
|
7
|
+
const TEST_FAULT_ENV = "LISA_TEST_RUN_TEST_FAULT";
|
|
8
|
+
/**
|
|
9
|
+
* Whether one companion has already reached a terminal child-process state.
|
|
10
|
+
* @param child - Protocol companion
|
|
11
|
+
* @returns Whether Node has recorded an exit code or terminal signal
|
|
12
|
+
*/
|
|
13
|
+
function companionExited(child) {
|
|
14
|
+
return child.exitCode !== null || child.signalCode !== null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Arm one listener-first, cancellable, bounded companion-exit wait.
|
|
18
|
+
* @param child - Protocol companion
|
|
19
|
+
* @returns Exit promise and listener/timer cancellation
|
|
20
|
+
*/
|
|
21
|
+
function boundedExitWait(child) {
|
|
22
|
+
const controller = new AbortController();
|
|
23
|
+
const exitEvent = once(child, "exit", { signal: controller.signal }).then(() => undefined);
|
|
24
|
+
const observedExit = companionExited(child) ? Promise.resolve() : exitEvent;
|
|
25
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
26
|
+
const timer = setTimeout(() => reject(new Error("Timed out waiting for bootstrap shutdown")), ACK_TIMEOUT_MS);
|
|
27
|
+
controller.signal.addEventListener("abort", () => clearTimeout(timer), {
|
|
28
|
+
once: true,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
promise: Promise.race([observedExit, timeout]).finally(() => controller.abort()),
|
|
33
|
+
cancel: () => controller.abort(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Deterministic test-only representation of a closed IPC transport. */
|
|
37
|
+
class ClosedIpcChannelError extends Error {
|
|
38
|
+
code = "ERR_IPC_CHANNEL_CLOSED";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Wait for one exact child acknowledgement or fail closed.
|
|
42
|
+
* @param child - Protocol companion
|
|
43
|
+
* @param expected - Exact expected type
|
|
44
|
+
* @param correlation - Optional exact root token
|
|
45
|
+
* @returns Promise settled by the exact validated acknowledgement
|
|
46
|
+
*/
|
|
47
|
+
export function waitForMessage(child, expected, correlation) {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const timer = setTimeout(() => {
|
|
50
|
+
cleanup();
|
|
51
|
+
reject(new Error(`Timed out waiting for ${expected}`));
|
|
52
|
+
}, ACK_TIMEOUT_MS);
|
|
53
|
+
const onMessage = (message) => {
|
|
54
|
+
try {
|
|
55
|
+
const value = parseScratchProtocolMessage(message);
|
|
56
|
+
if (value.type !== expected ||
|
|
57
|
+
(correlation !== undefined && value["correlation"] !== correlation) ||
|
|
58
|
+
(correlation === undefined && Object.hasOwn(value, "correlation"))) {
|
|
59
|
+
throw new Error(`Unexpected ${value.type} while waiting for ${expected}`);
|
|
60
|
+
}
|
|
61
|
+
cleanup();
|
|
62
|
+
resolve(value);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
cleanup();
|
|
66
|
+
reject(error);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const onExit = () => {
|
|
70
|
+
cleanup();
|
|
71
|
+
reject(new Error(`Protocol process exited before ${expected}`));
|
|
72
|
+
};
|
|
73
|
+
const cleanup = () => {
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
child.off("message", onMessage);
|
|
76
|
+
child.off("exit", onExit);
|
|
77
|
+
};
|
|
78
|
+
child.on("message", onMessage);
|
|
79
|
+
child.once("exit", onExit);
|
|
80
|
+
if (companionExited(child))
|
|
81
|
+
onExit();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Wait until a protocol companion is absent from the process table.
|
|
86
|
+
* @param child - Protocol companion
|
|
87
|
+
* @returns Promise settled after exit
|
|
88
|
+
*/
|
|
89
|
+
export function waitForExit(child) {
|
|
90
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
91
|
+
return Promise.resolve();
|
|
92
|
+
}
|
|
93
|
+
return new Promise(resolve => child.once("exit", () => resolve()));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Send one versioned message or reject a closed IPC channel.
|
|
97
|
+
* @param child - Protocol companion
|
|
98
|
+
* @param message - Exact message body without schema
|
|
99
|
+
* @returns Callback-settled send promise
|
|
100
|
+
*/
|
|
101
|
+
export function sendMessage(child, message) {
|
|
102
|
+
if (env[TEST_FAULT_ENV] === "signal-send-rejected" &&
|
|
103
|
+
message["type"] === "SIGNAL") {
|
|
104
|
+
return Promise.reject(new Error("deterministic signal-send rejection"));
|
|
105
|
+
}
|
|
106
|
+
if (env[TEST_FAULT_ENV] === "stop-send-rejected" &&
|
|
107
|
+
message["type"] === "STOP") {
|
|
108
|
+
return Promise.reject(new Error("deterministic STOP send rejection"));
|
|
109
|
+
}
|
|
110
|
+
if (env[TEST_FAULT_ENV] === "stop-send-closed" &&
|
|
111
|
+
message["type"] === "STOP") {
|
|
112
|
+
return new Promise((_resolve, reject) => {
|
|
113
|
+
child.send({ schema: 1, ...message }, () => {
|
|
114
|
+
reject(new ClosedIpcChannelError("deterministic closed STOP channel"));
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
child.send({ schema: 1, ...message }, error => {
|
|
120
|
+
if (error === null)
|
|
121
|
+
resolve();
|
|
122
|
+
else
|
|
123
|
+
reject(error);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Whether an IPC send failure proves the channel is already unusable.
|
|
129
|
+
* @param error - IPC callback or synchronous error
|
|
130
|
+
* @returns Whether the channel is conclusively closed
|
|
131
|
+
*/
|
|
132
|
+
function isClosedIpcError(error) {
|
|
133
|
+
const code = error.code;
|
|
134
|
+
return code === "ERR_IPC_CHANNEL_CLOSED" || code === "ERR_IPC_DISCONNECTED";
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Wait for the payload result and reject every other message.
|
|
138
|
+
* @param bootstrap - Inert bootstrap leader
|
|
139
|
+
* @param signalEscalating - Whether parent signal escalation owns its exit
|
|
140
|
+
* @returns Exact payload result
|
|
141
|
+
*/
|
|
142
|
+
export function waitForPayload(bootstrap, signalEscalating = () => false) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
const onMessage = (message) => {
|
|
145
|
+
try {
|
|
146
|
+
const value = parseScratchProtocolMessage(message);
|
|
147
|
+
if (value.type === "PAYLOAD_ERROR") {
|
|
148
|
+
throw new Error(value["message"]);
|
|
149
|
+
}
|
|
150
|
+
if (value.type !== "PAYLOAD_EXIT") {
|
|
151
|
+
throw new Error(`Unexpected ${value.type} during payload execution`);
|
|
152
|
+
}
|
|
153
|
+
cleanup();
|
|
154
|
+
resolve({
|
|
155
|
+
code: value["code"],
|
|
156
|
+
signal: value["signal"],
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
cleanup();
|
|
161
|
+
reject(error);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const onExit = () => {
|
|
165
|
+
cleanup();
|
|
166
|
+
if (signalEscalating())
|
|
167
|
+
return;
|
|
168
|
+
reject(new Error("Bootstrap exited before reporting payload result"));
|
|
169
|
+
};
|
|
170
|
+
const cleanup = () => {
|
|
171
|
+
bootstrap.off("message", onMessage);
|
|
172
|
+
bootstrap.off("exit", onExit);
|
|
173
|
+
};
|
|
174
|
+
bootstrap.on("message", onMessage);
|
|
175
|
+
bootstrap.once("exit", onExit);
|
|
176
|
+
if (companionExited(bootstrap))
|
|
177
|
+
onExit();
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Stop the inert leader and wait for it to leave the target group.
|
|
182
|
+
* @param bootstrap - Inert bootstrap leader
|
|
183
|
+
*/
|
|
184
|
+
export async function stopBootstrap(bootstrap) {
|
|
185
|
+
if (companionExited(bootstrap))
|
|
186
|
+
return;
|
|
187
|
+
const exitWait = boundedExitWait(bootstrap);
|
|
188
|
+
try {
|
|
189
|
+
await sendMessage(bootstrap, { type: "STOP" });
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (!companionExited(bootstrap) && !isClosedIpcError(error)) {
|
|
193
|
+
exitWait.cancel();
|
|
194
|
+
await exitWait.promise.catch(() => undefined);
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
await exitWait.promise;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=lisa-test-run-ipc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lisa-test-run-ipc.js","sourceRoot":"","sources":["../../src/cli/lisa-test-run-ipc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reject unsupported platforms before any scratch root or companion exists.
|
|
3
|
+
* @param platform - Runtime platform
|
|
4
|
+
*/
|
|
5
|
+
export declare function assertTestRunPlatform(platform?: NodeJS.Platform): void;
|
|
6
|
+
/** Armed bootstrap leader and process-group identity. */
|
|
7
|
+
export interface TestRunTargetIntent {
|
|
8
|
+
readonly pid: number;
|
|
9
|
+
readonly pgid: number;
|
|
10
|
+
readonly processBirthFingerprint: string;
|
|
11
|
+
}
|
|
12
|
+
/** Injectable probes used to deterministically prove fail-closed authority. */
|
|
13
|
+
export interface TestRunProcessGroupProbes {
|
|
14
|
+
readonly isProcessAlive: (pid: number) => boolean;
|
|
15
|
+
readonly processBirthFingerprint: (pid: number) => string | undefined;
|
|
16
|
+
readonly processGroupAlive: (pgid: number) => boolean;
|
|
17
|
+
readonly signalGroup: (pgid: number, signal: NodeJS.Signals) => void;
|
|
18
|
+
readonly delay: (milliseconds: number) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/** Optional probe overrides for one drain attempt. */
|
|
21
|
+
export interface DrainTestRunTargetOptions {
|
|
22
|
+
readonly probes?: Partial<TestRunProcessGroupProbes>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Drain only the group whose leader still has its armed process birth.
|
|
26
|
+
* @param target - Armed leader and group identity
|
|
27
|
+
* @param options - Optional deterministic probe overrides
|
|
28
|
+
*/
|
|
29
|
+
export declare function drainTestRunTarget(target: TestRunTargetIntent | undefined, options?: DrainTestRunTargetOptions): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=lisa-test-run-process-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lisa-test-run-process-group.d.ts","sourceRoot":"","sources":["../../src/cli/lisa-test-run-process-group.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,IAAI,CAMN;AAED,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;CAC1C;AAED,+EAA+E;AAC/E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD,QAAQ,CAAC,uBAAuB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACtE,QAAQ,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACtD,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IACrE,QAAQ,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED,sDAAsD;AACtD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;CACtD;AAqFD;;;;GAIG;AAEH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,GAAG,SAAS,EACvC,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,IAAI,CAAC,CAkCf"}
|