@zukhruf/testing 0.3.22 → 0.3.24

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @zukhruf/testing
2
2
 
3
- Disposable fixtures for integration tests on Node.js: Docker containers and database servers, SQLite and DuckDB databases, BigQuery datasets, HTTP servers and controlled streams. Each acquisition returns a handle that `await using` cleans up, also when the test fails. A background server has no handle: it lives until the process exits. A supervisor removes what a killed test run left behind.
3
+ Disposable fixtures for integration tests on Node.js: Docker containers and database servers, SQLite and DuckDB databases, BigQuery datasets, HTTP servers and controlled streams. Each acquisition returns a handle that `await using` cleans up, also when the test fails. A background server has no handle: it lives until the process exits. Node's global setup and global teardown remove what a killed test run left behind.
4
4
 
5
5
  The words in these documents have one meaning each. See the glossary in [CONTEXT.md](./CONTEXT.md).
6
6
 
@@ -118,19 +118,33 @@ docker stop <container-id>
118
118
 
119
119
  They run with `--rm`, so stopping also removes them. The image tag is part of the configuration: stop the server to pick up a newer image behind the same tag.
120
120
 
121
- ## The supervisor
121
+ ## A killed run
122
122
 
123
- Disposal cleans up after a test that ends. A test process that is killed (a timeout, Ctrl-C, `--test-force-exit`) never disposes its handles, and a running container does not stop by itself. The `zukhruf-docker-tests` command runs `node --test` as one supervised run:
123
+ Disposal cleans up after a test that ends. A test process that is killed (a timeout with `--test-force-exit`, Ctrl-C, an out-of-memory kill) does not dispose its handles. A running container does not stop by itself. Thus Node's global setup and global teardown make the test processes of one `node --test` invocation into one run. Re-export the two functions from one file in your project:
124
+
125
+ ```ts
126
+ // src/testing/docker-global-setup.ts
127
+ export {
128
+ globalSetup,
129
+ globalTeardown,
130
+ } from '@zukhruf/testing/docker-global-setup';
131
+ ```
132
+
133
+ Then give the file to `node --test`. The value is a path relative to the working directory. Node does not accept a package name there.
124
134
 
125
135
  ```sh
126
- zukhruf-docker-tests --test-force-exit "src/**/*.test.ts"
136
+ node --test --test-force-exit --test-global-setup=src/testing/docker-global-setup.ts "src/**/*.test.ts"
127
137
  ```
128
138
 
129
- It passes its arguments to `node --test`, and sets `ZUKHRUF_TESTING_RUN_ID` and `ZUKHRUF_TESTING_RUN_DIR` for the test processes. A `Docker` built with `TestRun.fromEnvironment(process.env)` labels what it creates with the run, and records SSH forwards and host directories in the run's directory. When the test processes exit, the supervisor stops their process group and removes the labeled containers with their anonymous volumes, the labeled volumes and the recorded paths. It never removes shared servers.
139
+ The global setup sets `ZUKHRUF_TESTING_RUN_ID` and `ZUKHRUF_TESTING_RUN_DIR` for the test processes. A `Docker` built with `TestRun.fromEnvironment(process.env)` labels what it creates with the run. It records SSH forwards and host directories in the run's directory. It also writes a process record for its test process, and for each Docker or SSH command that it starts, while that command runs.
140
+
141
+ The global teardown removes the labeled containers with their anonymous volumes, the labeled volumes and the recorded paths. It never removes shared servers. The teardown is synchronous, because Node does not wait for an asynchronous teardown under `--test-force-exit`. When every recorded process has ended, the teardown deletes the run's records. A recorded process that still runs can still create a container, for example a `docker run` that a killed test process started. Then the teardown keeps the records, and a later run removes what is left after that process ends.
142
+
143
+ If cleanup fails, for example because the engine is unreachable, the global teardown prints the error, keeps the run's records, and sets exit code 1. The next run on the same engine removes what the run left, from any project of this user. This is recovery. Recovery does not touch a run while its runner or one of its recorded processes lives. The records are in `$XDG_STATE_HOME/zukhruf-testing/docker-runs` (`~/.local/state/zukhruf-testing/docker-runs` by default). Do not delete a record to hide a cleanup failure.
130
144
 
131
- If cleanup fails, for example because the engine is unreachable, the supervisor exits with an error and keeps the run's record. The next run on the same engine removes what it left, from any project of this user. The records are in `$XDG_STATE_HOME/zukhruf-testing/docker-runs` (`~/.local/state/zukhruf-testing/docker-runs` by default). Never delete a record to hide a cleanup failure.
145
+ The global setup reads the engine with `docker context inspect`, so the Docker CLI must be installed. It calls the engine only when a dead run on that engine has records of processes to sweep.
132
146
 
133
- On an SSH engine the supervisor runs one test file at a time, unless you pass `--test-concurrency`. It runs on Linux and macOS: it stops a run as a process group, which Windows does not have.
147
+ On an SSH engine, run one test file at a time with `--test-concurrency=1` if the engine cannot take more. An SSH forward runs `cat` in a remote shell, so the SSH user needs a shell on the engine's host. The forward ends when the process that opened it ends, also when that process is killed.
134
148
 
135
149
  To pass the run to another container API, spread `docker.defaults`: it holds the default `resources` and the run's `labels`.
136
150
 
@@ -34,7 +34,7 @@ export interface ServiceOptions extends ContainerOptions {
34
34
  healthy?: (container: ServiceContainer) => unknown;
35
35
  }
36
36
  export interface DockerOptions {
37
- /** The supervised run that owns what this process creates: `TestRun.fromEnvironment(process.env)`. */
37
+ /** The run that owns what this process creates: `TestRun.fromEnvironment(process.env)`. */
38
38
  testRun?: TestRun | undefined;
39
39
  }
40
40
  /** The engine the Docker CLI selects. Docker owns cross-process coordination; this instance holds no server cache. */
@@ -54,7 +54,7 @@ export declare class Docker {
54
54
  endpoint: string;
55
55
  }>;
56
56
  directory(): Promise<DockerDirectory>;
57
- /** Creates a named volume. The supervisor removes it with its run if this process dies first. */
57
+ /** Creates a named volume. Its run's cleanup removes it if this process dies first. */
58
58
  volume(): Promise<DockerVolume>;
59
59
  readonly command: DockerCommand;
60
60
  isAvailable(): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/docker/docker.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,sEAAsE;AACtE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAGhE,yEAAyE;AACzE,MAAM,WAAW,KAAK;IACpB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,wGAAwG;IACxG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC5C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,OAAO,CAAC;CACpD;AAED,MAAM,WAAW,aAAa;IAC5B,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AA2BD,sHAAsH;AACtH,qBAAa,MAAM;;gBAaL,EAAE,OAAO,EAAE,GAAE,aAAkB;IAI3C,6EAA6E;IAC7E,IAAI,QAAQ,IAAI;QACd,SAAS,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAKA;IAEK,IAAI,IAAI,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAU3D,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAI3C,iGAAiG;IAC3F,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAYrC,QAAQ,CAAC,OAAO,EAAE,aAAa,CACY;IAErC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAarC,gGAAgG;IAC1F,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC;IAK1D,gGAAgG;IAC1F,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAe/D;;;;OAIG;IACG,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqB/D,2GAA2G;IACrG,GAAG,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAgLtD"}
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/docker/docker.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,sEAAsE;AACtE,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAGhE,yEAAyE;AACzE,MAAM,WAAW,KAAK;IACpB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,wGAAwG;IACxG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC5C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,OAAO,CAAC;CACpD;AAED,MAAM,WAAW,aAAa;IAC5B,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AA2BD,sHAAsH;AACtH,qBAAa,MAAM;;gBAcL,EAAE,OAAO,EAAE,GAAE,aAAkB;IAI3C,6EAA6E;IAC7E,IAAI,QAAQ,IAAI;QACd,SAAS,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAKA;IAEK,IAAI,IAAI,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAU3D,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAI3C,uFAAuF;IACjF,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAYrC,QAAQ,CAAC,OAAO,EAAE,aAAa,CACY;IAErC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAarC,gGAAgG;IAC1F,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC;IAK1D,gGAAgG;IAC1F,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAe/D;;;;OAIG;IACG,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqB/D,2GAA2G;IACrG,GAAG,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CA6KtD"}
@@ -27,8 +27,9 @@ const byKey = ([a], [b]) => {
27
27
  /** The engine the Docker CLI selects. Docker owns cross-process coordination; this instance holds no server cache. */
28
28
  export class Docker {
29
29
  #testRun;
30
- // The first resolution pins the engine: handles keep the engine they were made on.
31
- #connection = pMemoize(() => DockerHost.resolve());
30
+ // The first resolution pins the engine: handles keep the engine they were
31
+ // made on. It records this process in the run before any command runs.
32
+ #connection = pMemoize(() => DockerHost.resolve(this.#testRun));
32
33
  #probe = pMemoize(async () => {
33
34
  try {
34
35
  await this.command(['info']);
@@ -60,7 +61,7 @@ export class Docker {
60
61
  async directory() {
61
62
  return DockerDirectory.create(await this.#connection(), this.#testRun);
62
63
  }
63
- /** Creates a named volume. The supervisor removes it with its run if this process dies first. */
64
+ /** Creates a named volume. Its run's cleanup removes it if this process dies first. */
64
65
  async volume() {
65
66
  const host = await this.#require();
66
67
  const name = `zukhruf-testing-${randomUUID()}`;
@@ -242,7 +243,7 @@ export class Docker {
242
243
  const port = /:(\d+)$/.exec(stdout.trim())?.[1];
243
244
  if (!port)
244
245
  throw new Error(`Failed to get mapped port for container ${id}: ${stdout}`);
245
- const connection = await host.forward(Number.parseInt(port, 10), this.#testRun);
246
+ const connection = await host.forward(Number.parseInt(port, 10));
246
247
  const container = new ServiceContainer(id, connection.port, host.command, connection.close);
247
248
  try {
248
249
  await healthy?.(container);
@@ -1 +1 @@
1
- {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/docker/docker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/docker/docker.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,28 @@
1
+ import { type Result } from 'nano-spawn';
1
2
  import { type TestRun } from './test-run.ts';
2
3
  export declare const quote: (value: string) => string;
3
- /** Resolve with the Docker CLI so its native context/environment precedence wins. */
4
+ /** How long one Docker CLI call may take before this process stops it. */
5
+ export declare const DOCKER_COMMAND_TIMEOUT = 240000;
6
+ /** How long one command in the SSH engine's remote shell may take. */
7
+ export declare const SHELL_TIMEOUT = 30000;
8
+ /** The environment that points the Docker CLI at `endpoint`, whatever context is selected. */
9
+ export declare const dockerEnvironment: (endpoint: string) => Record<string, string | undefined>;
10
+ /**
11
+ * An engine endpoint. Resolve it with the Docker CLI so its native
12
+ * context/environment precedence wins. With a run, each command it starts
13
+ * has a process record while it runs.
14
+ */
4
15
  export declare class DockerHost {
16
+ #private;
5
17
  readonly endpoint: string;
6
- private constructor();
7
- static resolve(): Promise<DockerHost>;
18
+ constructor(endpoint: string, run: TestRun | undefined);
19
+ /** The engine the Docker CLI selects. A run gets this process's process record. */
20
+ static resolve(run: TestRun | undefined): Promise<DockerHost>;
8
21
  get remote(): boolean;
9
- readonly command: (args: string[]) => import("nano-spawn").Subprocess;
22
+ readonly command: (args: string[]) => Promise<Result>;
10
23
  sshArgs(options?: string[]): string[];
11
- shell(script: string, input?: string): import("nano-spawn").Subprocess;
12
- forward(port: number, run: TestRun | undefined): Promise<{
24
+ shell(script: string, input?: string): Promise<Result>;
25
+ forward(port: number): Promise<{
13
26
  port: number;
14
27
  close: () => Promise<void>;
15
28
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/docker/host.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,eAAe,CAAC;AAE5D,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,MACC,CAAC;AAKxC,qFAAqF;AACrF,qBAAa,UAAU;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,OAAO;WAIM,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAgB3C,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,QAAQ,CAAC,OAAO,GAAI,MAAM,MAAM,EAAE,qCAI7B;IAEL,OAAO,CAAC,OAAO,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE;IAqBzC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAO9B,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,GAAG,SAAS,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;CAuIzD"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/docker/host.ts"],"names":[],"mappings":"AAKA,OAAgB,EACd,KAAK,MAAM,EAGZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,eAAe,CAAC;AAE5D,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,MACC,CAAC;AAExC,0EAA0E;AAC1E,eAAO,MAAM,sBAAsB,SAAU,CAAC;AAC9C,sEAAsE;AACtE,eAAO,MAAM,aAAa,QAAS,CAAC;AAEpC,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,GAC5B,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAGlC,CAAC;AAKH;;;;GAIG;AACH,qBAAa,UAAU;;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAGd,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,SAAS;IAUtD,mFAAmF;WACtE,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAYnE,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,QAAQ,CAAC,OAAO,GAAI,MAAM,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAAC,CAMhD;IAeJ,OAAO,CAAC,OAAO,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE;IAqBzC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAShD,OAAO,CACX,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;CAkJzD"}
@@ -2,38 +2,69 @@ import { once } from 'node:events';
2
2
  import { mkdtempDisposable, stat } from 'node:fs/promises';
3
3
  import { connect, createServer } from 'node:net';
4
4
  import { join } from 'node:path';
5
- import command, { SubprocessError } from 'nano-spawn';
5
+ import command, { SubprocessError, } from 'nano-spawn';
6
6
  import { timebox } from "../async/timebox.js";
7
7
  import { forwardPrefix } from "./test-run.js";
8
8
  export const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
9
+ /** How long one Docker CLI call may take before this process stops it. */
10
+ export const DOCKER_COMMAND_TIMEOUT = 240_000;
11
+ /** How long one command in the SSH engine's remote shell may take. */
12
+ export const SHELL_TIMEOUT = 30_000;
13
+ /** The environment that points the Docker CLI at `endpoint`, whatever context is selected. */
14
+ export const dockerEnvironment = (endpoint) => ({
15
+ DOCKER_CONTEXT: undefined,
16
+ DOCKER_HOST: endpoint,
17
+ });
9
18
  /** Local Unix sockets, Docker Desktop's named pipe on Windows, and SSH engines. A `tcp://` engine may be on another machine. */
10
19
  const supportedEndpoints = ['unix://', 'npipe://', 'ssh://'];
11
- /** Resolve with the Docker CLI so its native context/environment precedence wins. */
20
+ /**
21
+ * An engine endpoint. Resolve it with the Docker CLI so its native
22
+ * context/environment precedence wins. With a run, each command it starts
23
+ * has a process record while it runs.
24
+ */
12
25
  export class DockerHost {
13
26
  endpoint;
14
- constructor(endpoint) {
27
+ #run;
28
+ constructor(endpoint, run) {
29
+ if (!supportedEndpoints.some((scheme) => endpoint.startsWith(scheme))) {
30
+ throw new Error(`Unsupported Docker endpoint ${endpoint}; tests support ${supportedEndpoints.join(', ')}`);
31
+ }
15
32
  this.endpoint = endpoint;
33
+ this.#run = run;
16
34
  }
17
- static async resolve() {
35
+ /** The engine the Docker CLI selects. A run gets this process's process record. */
36
+ static async resolve(run) {
18
37
  const { stdout } = await command('docker', [
19
38
  'context',
20
39
  'inspect',
21
40
  '--format',
22
41
  '{{.Endpoints.docker.Host}}',
23
42
  ]);
24
- const endpoint = stdout.trim();
25
- if (!supportedEndpoints.some((scheme) => endpoint.startsWith(scheme))) {
26
- throw new Error(`Unsupported Docker endpoint ${endpoint}; tests support ${supportedEndpoints.join(', ')}`);
27
- }
28
- return new DockerHost(endpoint);
43
+ const host = new DockerHost(stdout.trim(), run);
44
+ await run?.recordProcess(process.pid);
45
+ return host;
29
46
  }
30
47
  get remote() {
31
48
  return this.endpoint.startsWith('ssh://');
32
49
  }
33
- command = (args) => command('docker', args, {
34
- env: { DOCKER_CONTEXT: undefined, DOCKER_HOST: this.endpoint },
35
- timeout: 240_000,
36
- });
50
+ command = (args) => this.#recorded(command('docker', args, {
51
+ env: dockerEnvironment(this.endpoint),
52
+ timeout: DOCKER_COMMAND_TIMEOUT,
53
+ }));
54
+ /** A killed process leaves its commands running; their records keep its run until they end. */
55
+ async #recorded(subprocess) {
56
+ if (!this.#run)
57
+ return subprocess;
58
+ // Awaited below; a command that fails while its record is written must
59
+ // not count as an unhandled rejection.
60
+ subprocess.catch(() => { });
61
+ const { pid } = await subprocess.nodeChildProcess;
62
+ // Node leaves pid undefined when the spawn failed: no process to record.
63
+ if (pid === undefined)
64
+ return subprocess;
65
+ await using _record = await this.#run.recordProcess(pid);
66
+ return await subprocess;
67
+ }
37
68
  sshArgs(options = []) {
38
69
  const url = new URL(this.endpoint);
39
70
  // Pass the original hostname to OpenSSH: ~/.ssh/config, jump hosts, keys,
@@ -55,12 +86,13 @@ export class DockerHost {
55
86
  ];
56
87
  }
57
88
  shell(script, input) {
58
- return command('ssh', [...this.sshArgs(), script], {
89
+ return this.#recorded(command('ssh', [...this.sshArgs(), script], {
59
90
  stdin: input === undefined ? 'ignore' : { string: input },
60
- timeout: 30_000,
61
- });
91
+ timeout: SHELL_TIMEOUT,
92
+ }));
62
93
  }
63
- async forward(port, run) {
94
+ async forward(port) {
95
+ const run = this.#run;
64
96
  if (!this.remote)
65
97
  return { port, close: async () => { } };
66
98
  const resources = new AsyncDisposableStack();
@@ -92,19 +124,26 @@ export class DockerHost {
92
124
  // OpenSSH multiplexes client streams over one authenticated connection.
93
125
  // Node owns the ephemeral TCP listener, so no port-reservation race or
94
126
  // fresh SSH login is added to each database client's connect timeout.
95
- const ssh = command('ssh', this.sshArgs([
96
- '-N',
97
- '-S',
98
- 'none',
99
- '-o',
100
- 'ControlMaster=no',
101
- '-o',
102
- 'ControlPersist=no',
103
- '-o',
104
- 'ExitOnForwardFailure=yes',
105
- '-L',
106
- `${path}:127.0.0.1:${port}`,
107
- ]), { stdin: 'ignore', stdout: 'ignore' });
127
+ // A remote `cat` on a stdin pipe this process holds, not -N: when this
128
+ // process dies, even by SIGKILL, the OS closes the pipe, `cat` reads
129
+ // EOF and ssh exits instead of staying connected under PID 1. The
130
+ // command needs a remote shell, which the Docker CLI over ssh already
131
+ // uses to run `docker system dial-stdio`.
132
+ const ssh = command('ssh', [
133
+ ...this.sshArgs([
134
+ '-S',
135
+ 'none',
136
+ '-o',
137
+ 'ControlMaster=no',
138
+ '-o',
139
+ 'ControlPersist=no',
140
+ '-o',
141
+ 'ExitOnForwardFailure=yes',
142
+ '-L',
143
+ `${path}:127.0.0.1:${port}`,
144
+ ]),
145
+ 'cat >/dev/null',
146
+ ], { stdin: 'pipe', stdout: 'ignore' });
108
147
  // How ssh ended, with what it printed: a Result for exit 0, or the
109
148
  // SubprocessError for a failure or a signal.
110
149
  const exit = ssh.then((result) => result, (error) => {
@@ -119,8 +158,11 @@ export class DockerHost {
119
158
  server.close();
120
159
  });
121
160
  const child = await ssh.nodeChildProcess;
161
+ // Disposed after ssh has stopped.
162
+ if (run && child.pid !== undefined)
163
+ resources.use(await run.recordProcess(child.pid));
122
164
  resources.defer(async () => {
123
- child.kill('SIGTERM');
165
+ child.stdin.end();
124
166
  const deadline = setTimeout(() => child.kill('SIGKILL'), 1_000);
125
167
  try {
126
168
  await exit;
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/docker/host.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/docker/host.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,34 @@
1
- /** Set by the supervisor for the test processes it starts: the run's id. */
1
+ /** Set by the global setup for the run's test processes: the run's id. */
2
2
  export declare const TEST_RUN_ID = "ZUKHRUF_TESTING_RUN_ID";
3
- /** Set by the supervisor for the test processes it starts: the run's records. */
3
+ /** Set by the global setup for the run's test processes: the run's records. */
4
4
  export declare const TEST_RUN_DIRECTORY = "ZUKHRUF_TESTING_RUN_DIR";
5
5
  /** The label that ties a container or volume to the run that created it. */
6
6
  export declare const TEST_RUN_LABEL = "dev.zukhruf.testing.run";
7
7
  /**
8
- * One supervised `node --test` invocation. What its test processes create
9
- * carries the run's label or a record in the run's directory, so the
10
- * supervisor removes it after a process that was killed before it could.
8
+ * One `node --test` invocation with the Docker global setup. What its test
9
+ * processes create carries the run's label or a record in the run's
10
+ * directory, so the global teardown, or the recovery of a later run, removes
11
+ * it after a process that was killed before it could.
11
12
  */
12
13
  export declare class TestRun {
13
14
  readonly id: string;
14
15
  readonly directory: string;
15
16
  constructor(id: string, directory: string);
16
17
  /**
17
- * The run the supervisor started this process in, read from the environment
18
- * the host passes (`process.env`). Undefined outside a supervisor.
18
+ * The run the global setup started this process in, read from the
19
+ * environment the host passes (`process.env`). Undefined outside a run.
19
20
  */
20
21
  static fromEnvironment(environment: Readonly<Record<string, string | undefined>>): TestRun | undefined;
21
22
  get labels(): Record<string, string>;
22
23
  /**
23
- * Records a path that the supervisor removes if this process dies first.
24
+ * Writes a process record for `pid`, a test process or a command it
25
+ * started. While a recorded process lives, the run's records stay.
26
+ * Disposing the record forgets a command that ended. The random id keeps
27
+ * a reused pid from deleting the record of the next command that has it.
28
+ */
29
+ recordProcess(pid: number): Promise<AsyncDisposable>;
30
+ /**
31
+ * Records a path that the global teardown removes if this process dies first.
24
32
  * Disposing the record forgets the path once the process removed it itself.
25
33
  */
26
34
  record(kind: 'forward' | 'directory', path: string): Promise<AsyncDisposable>;
@@ -1 +1 @@
1
- {"version":3,"file":"test-run.d.ts","sourceRoot":"","sources":["../../src/docker/test-run.ts"],"names":[],"mappings":"AAIA,4EAA4E;AAC5E,eAAO,MAAM,WAAW,2BAA2B,CAAC;AACpD,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAC5D,4EAA4E;AAC5E,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD;;;;GAIG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAKzC;;;OAGG;IACH,MAAM,CAAC,eAAe,CACpB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GACxD,OAAO,GAAG,SAAS;IAWtB,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnC;IAED;;;OAGG;IACG,MAAM,CACV,IAAI,EAAE,SAAS,GAAG,WAAW,EAC7B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,CAAC;CAK5B;AAED,6EAA6E;AAC7E,eAAO,MAAM,eAAe,GAAI,KAAK,OAAO,GAAG,SAAS,KAAG,MACZ,CAAC;AAEhD,2EAA2E;AAC3E,eAAO,MAAM,aAAa,GAAI,KAAK,OAAO,GAAG,SAAS,KAAG,MACG,CAAC"}
1
+ {"version":3,"file":"test-run.d.ts","sourceRoot":"","sources":["../../src/docker/test-run.ts"],"names":[],"mappings":"AAIA,0EAA0E;AAC1E,eAAO,MAAM,WAAW,2BAA2B,CAAC;AACpD,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAC5D,4EAA4E;AAC5E,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD;;;;;GAKG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAKzC;;;OAGG;IACH,MAAM,CAAC,eAAe,CACpB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GACxD,OAAO,GAAG,SAAS;IAWtB,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnC;IAED;;;;;OAKG;IACG,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAM1D;;;OAGG;IACG,MAAM,CACV,IAAI,EAAE,SAAS,GAAG,WAAW,EAC7B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,CAAC;CAK5B;AAED,6EAA6E;AAC7E,eAAO,MAAM,eAAe,GAAI,KAAK,OAAO,GAAG,SAAS,KAAG,MACZ,CAAC;AAEhD,2EAA2E;AAC3E,eAAO,MAAM,aAAa,GAAI,KAAK,OAAO,GAAG,SAAS,KAAG,MACG,CAAC"}
@@ -1,16 +1,17 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { rm, writeFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
- /** Set by the supervisor for the test processes it starts: the run's id. */
4
+ /** Set by the global setup for the run's test processes: the run's id. */
5
5
  export const TEST_RUN_ID = 'ZUKHRUF_TESTING_RUN_ID';
6
- /** Set by the supervisor for the test processes it starts: the run's records. */
6
+ /** Set by the global setup for the run's test processes: the run's records. */
7
7
  export const TEST_RUN_DIRECTORY = 'ZUKHRUF_TESTING_RUN_DIR';
8
8
  /** The label that ties a container or volume to the run that created it. */
9
9
  export const TEST_RUN_LABEL = 'dev.zukhruf.testing.run';
10
10
  /**
11
- * One supervised `node --test` invocation. What its test processes create
12
- * carries the run's label or a record in the run's directory, so the
13
- * supervisor removes it after a process that was killed before it could.
11
+ * One `node --test` invocation with the Docker global setup. What its test
12
+ * processes create carries the run's label or a record in the run's
13
+ * directory, so the global teardown, or the recovery of a later run, removes
14
+ * it after a process that was killed before it could.
14
15
  */
15
16
  export class TestRun {
16
17
  id;
@@ -20,8 +21,8 @@ export class TestRun {
20
21
  this.directory = directory;
21
22
  }
22
23
  /**
23
- * The run the supervisor started this process in, read from the environment
24
- * the host passes (`process.env`). Undefined outside a supervisor.
24
+ * The run the global setup started this process in, read from the
25
+ * environment the host passes (`process.env`). Undefined outside a run.
25
26
  */
26
27
  static fromEnvironment(environment) {
27
28
  const id = environment[TEST_RUN_ID];
@@ -29,14 +30,25 @@ export class TestRun {
29
30
  if (id === undefined && directory === undefined)
30
31
  return undefined;
31
32
  if (!id || !directory)
32
- throw new Error(`The supervisor sets ${TEST_RUN_ID} and ${TEST_RUN_DIRECTORY} together, but only one of them is set`);
33
+ throw new Error(`The global setup sets ${TEST_RUN_ID} and ${TEST_RUN_DIRECTORY} together, but only one of them is set`);
33
34
  return new TestRun(id, directory);
34
35
  }
35
36
  get labels() {
36
37
  return { [TEST_RUN_LABEL]: this.id };
37
38
  }
38
39
  /**
39
- * Records a path that the supervisor removes if this process dies first.
40
+ * Writes a process record for `pid`, a test process or a command it
41
+ * started. While a recorded process lives, the run's records stay.
42
+ * Disposing the record forgets a command that ended. The random id keeps
43
+ * a reused pid from deleting the record of the next command that has it.
44
+ */
45
+ async recordProcess(pid) {
46
+ const file = join(this.directory, `process-${pid}-${randomUUID()}.json`);
47
+ await writeFile(file, JSON.stringify({ pid }));
48
+ return { [Symbol.asyncDispose]: () => rm(file, { force: true }) };
49
+ }
50
+ /**
51
+ * Records a path that the global teardown removes if this process dies first.
40
52
  * Disposing the record forgets the path once the process removed it itself.
41
53
  */
42
54
  async record(kind, path) {
@@ -1 +1 @@
1
- {"version":3,"file":"test-run.js","sourceRoot":"","sources":["../../src/docker/test-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AACpD,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAC5D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAExD;;;;GAIG;AACH,MAAM,OAAO,OAAO;IACT,EAAE,CAAS;IACX,SAAS,CAAS;IAE3B,YAAY,EAAU,EAAE,SAAiB;QACvC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,eAAe,CACpB,WAAyD;QAEzD,MAAM,EAAE,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,EAAE,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAClE,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS;YACnB,MAAM,IAAI,KAAK,CACb,uBAAuB,WAAW,QAAQ,kBAAkB,wCAAwC,CACrG,CAAC;QACJ,OAAO,IAAI,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CACV,IAA6B,EAC7B,IAAY;QAEZ,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,UAAU,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,OAAO,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpE,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAwB,EAAU,EAAE,CAClE,mBAAmB,GAAG,EAAE,EAAE,IAAI,YAAY,GAAG,CAAC;AAEhD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAwB,EAAU,EAAE,CAChE,gCAAgC,GAAG,EAAE,EAAE,IAAI,YAAY,GAAG,CAAC"}
1
+ {"version":3,"file":"test-run.js","sourceRoot":"","sources":["../../src/docker/test-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AACpD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAC5D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,OAAO,OAAO;IACT,EAAE,CAAS;IACX,SAAS,CAAS;IAE3B,YAAY,EAAU,EAAE,SAAiB;QACvC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,eAAe,CACpB,WAAyD;QAEzD,MAAM,EAAE,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,EAAE,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAClE,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS;YACnB,MAAM,IAAI,KAAK,CACb,yBAAyB,WAAW,QAAQ,kBAAkB,wCAAwC,CACvG,CAAC;QACJ,OAAO,IAAI,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,GAAW;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,UAAU,EAAE,OAAO,CAAC,CAAC;QACzE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CACV,IAA6B,EAC7B,IAAY;QAEZ,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,UAAU,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,OAAO,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpE,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAwB,EAAU,EAAE,CAClE,mBAAmB,GAAG,EAAE,EAAE,IAAI,YAAY,GAAG,CAAC;AAEhD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAwB,EAAU,EAAE,CAChE,gCAAgC,GAAG,EAAE,EAAE,IAAI,YAAY,GAAG,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function globalSetup(): Promise<void>;
2
+ /** Synchronous, like cleanup, so that `--test-force-exit` cannot cut it off. */
3
+ export declare function globalTeardown(): void;
4
+ //# sourceMappingURL=docker-global-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-global-setup.d.ts","sourceRoot":"","sources":["../../src/scripts/docker-global-setup.ts"],"names":[],"mappings":"AAkNA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA2BjD;AAED,gFAAgF;AAChF,wBAAgB,cAAc,IAAI,IAAI,CA0BrC"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * The Docker global setup and teardown for `node --test
3
+ * --test-global-setup=<file>`, where the file re-exports both functions. The
4
+ * setup starts one run: its test processes tie what they create to the run
5
+ * (see TestRun.fromEnvironment), and the teardown removes it after they exit.
6
+ * A run that was killed before it could is removed by a later run on the same
7
+ * engine, from any project of this user.
8
+ */
9
+ import { execFileSync } from 'node:child_process';
10
+ import { randomUUID } from 'node:crypto';
11
+ import { readFileSync, readdirSync, rmSync } from 'node:fs';
12
+ import { mkdir, readFile, readdir, rename, writeFile } from 'node:fs/promises';
13
+ import { homedir } from 'node:os';
14
+ import { join } from 'node:path';
15
+ import { SHARED_SERVER_LABEL } from "../docker/docker.js";
16
+ import { DOCKER_COMMAND_TIMEOUT, DockerHost, SHELL_TIMEOUT, dockerEnvironment, quote, } from "../docker/host.js";
17
+ import { TEST_RUN_DIRECTORY, TEST_RUN_ID, TEST_RUN_LABEL, TestRun, directoryPrefix, forwardPrefix, } from "../docker/test-run.js";
18
+ const codeOf = (error) => error instanceof Error && 'code' in error ? error.code : undefined;
19
+ /** What a failed execFileSync call printed: its error carries the output it captured. */
20
+ const stderrOf = (error) => error instanceof Error && 'stderr' in error ? String(error.stderr) : '';
21
+ function alive(pid) {
22
+ try {
23
+ process.kill(pid, 0);
24
+ return true;
25
+ }
26
+ catch (error) {
27
+ return codeOf(error) !== 'ESRCH';
28
+ }
29
+ }
30
+ /** Waits without returning to the event loop, which force-exit would end. */
31
+ const block = (milliseconds) => {
32
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
33
+ };
34
+ /** Ignores Docker's answer that `missing` names something already gone. */
35
+ const unlessMissing = (missing, error) => {
36
+ if (!missing.test(stderrOf(error)))
37
+ throw error;
38
+ };
39
+ function readRecordedPath(file) {
40
+ const { path } = JSON.parse(readFileSync(file, 'utf8'));
41
+ return path;
42
+ }
43
+ /** The pids in the run's process records. */
44
+ function recordedProcesses(directory) {
45
+ return readdirSync(directory).flatMap((file) => {
46
+ const pid = /^process-(\d+)-[\da-f-]{36}\.json$/.exec(file)?.[1];
47
+ return pid === undefined ? [] : [Number(pid)];
48
+ });
49
+ }
50
+ /**
51
+ * Removes what carries the run's label and what its records name. It is
52
+ * synchronous: under `--test-force-exit`, Node does not await the global
53
+ * teardown before it exits (internal/test_runner/test, `harness.teardown()`
54
+ * and then `process.exit()`).
55
+ */
56
+ function cleanup(host, run, directory) {
57
+ const docker = (args) => execFileSync('docker', args, {
58
+ encoding: 'utf8',
59
+ env: { ...process.env, ...dockerEnvironment(host.endpoint) },
60
+ stdio: ['ignore', 'pipe', 'pipe'],
61
+ timeout: DOCKER_COMMAND_TIMEOUT,
62
+ }).trim();
63
+ const owner = new TestRun(run.id, directory);
64
+ // Labels are attached atomically at creation. Never prune a daemon, remove
65
+ // shared servers, or trust names alone as proof of ownership.
66
+ const filter = ['--filter', `label=${TEST_RUN_LABEL}=${run.id}`];
67
+ for (const id of docker(['ps', '-aq', ...filter])
68
+ .split('\n')
69
+ .filter(Boolean)) {
70
+ try {
71
+ const shared = docker([
72
+ 'inspect',
73
+ '--format',
74
+ `{{index .Config.Labels "${SHARED_SERVER_LABEL}"}}`,
75
+ id,
76
+ ]);
77
+ if (shared !== '1')
78
+ remove(docker, id);
79
+ }
80
+ catch (error) {
81
+ unlessMissing(/No such (object|container)/i, error);
82
+ }
83
+ }
84
+ for (const name of docker(['volume', 'ls', '-q', ...filter])
85
+ .split('\n')
86
+ .filter(Boolean)) {
87
+ try {
88
+ docker(['volume', 'rm', name]);
89
+ }
90
+ catch (error) {
91
+ unlessMissing(/no such volume|volume \S+ not found/i, error);
92
+ }
93
+ }
94
+ for (const file of readdirSync(directory)) {
95
+ if (file.startsWith('forward-')) {
96
+ const path = readRecordedPath(join(directory, file));
97
+ if (!path.startsWith(forwardPrefix(owner)) || path.slice(5).includes('/'))
98
+ throw new Error(`Invalid SSH forwarding cleanup record: ${path}`);
99
+ rmSync(path, { recursive: true, force: true });
100
+ }
101
+ else if (file.startsWith('directory-')) {
102
+ const path = readRecordedPath(join(directory, file));
103
+ if (!path.includes(`/${directoryPrefix(owner)}`) || path.includes('/../'))
104
+ throw new Error(`Invalid fixture cleanup record: ${path}`);
105
+ if (host.remote)
106
+ execFileSync('ssh', [...host.sshArgs(), `rm -rf -- ${quote(path)}`], {
107
+ stdio: ['ignore', 'pipe', 'pipe'],
108
+ timeout: SHELL_TIMEOUT,
109
+ });
110
+ else
111
+ rmSync(path, { recursive: true, force: true });
112
+ }
113
+ }
114
+ }
115
+ /**
116
+ * A test process that stops its --rm server as it exits makes Docker refuse
117
+ * this removal until its own one ends; retry until the container is gone.
118
+ */
119
+ function remove(docker, id) {
120
+ const deadline = Date.now() + DOCKER_COMMAND_TIMEOUT;
121
+ for (;;) {
122
+ try {
123
+ docker(['rm', '--force', '--volumes', id]);
124
+ return;
125
+ }
126
+ catch (error) {
127
+ if (Date.now() > deadline ||
128
+ !/removal of container \S+ is already in progress/.test(stderrOf(error)))
129
+ throw error;
130
+ block(250);
131
+ }
132
+ }
133
+ }
134
+ async function readRun(directory) {
135
+ try {
136
+ return JSON.parse(await readFile(join(directory, 'run.json'), 'utf8'));
137
+ }
138
+ catch {
139
+ // Its global setup may still be writing it, or another one just claimed it.
140
+ return undefined;
141
+ }
142
+ }
143
+ /** Removes what dead runs on this engine left behind. */
144
+ async function recover(root, host) {
145
+ for (const name of await readdir(root)) {
146
+ // A claim names its runner: while it lives, the run is being recovered.
147
+ const claimant = /^recovering-(\d+)-/.exec(name)?.[1];
148
+ if (claimant !== undefined && alive(Number(claimant)))
149
+ continue;
150
+ const directory = join(root, name);
151
+ const previous = await readRun(directory);
152
+ if (!previous || previous.endpoint !== host.endpoint || alive(previous.pid))
153
+ continue;
154
+ // A killed runner leaves its test processes, and a killed test process
155
+ // its Docker commands, running. Each one can still create something.
156
+ let processes;
157
+ try {
158
+ processes = recordedProcesses(directory);
159
+ }
160
+ catch (error) {
161
+ // Another runner claimed the run between the listing and this read.
162
+ if (codeOf(error) === 'ENOENT')
163
+ continue;
164
+ throw error;
165
+ }
166
+ if (processes.some(alive))
167
+ continue;
168
+ // Runners start in parallel; the rename lets exactly one recover a run.
169
+ const claimed = join(root, `recovering-${process.pid}-${randomUUID()}`);
170
+ try {
171
+ await rename(directory, claimed);
172
+ }
173
+ catch (error) {
174
+ if (codeOf(error) === 'ENOENT')
175
+ continue;
176
+ throw error;
177
+ }
178
+ try {
179
+ if (processes.length > 0)
180
+ cleanup(host, previous, claimed);
181
+ rmSync(claimed, { recursive: true, force: true });
182
+ }
183
+ catch (error) {
184
+ throw new Error(`Could not recover Docker test resources. Retained ownership record: ${claimed}`, { cause: error });
185
+ }
186
+ }
187
+ }
188
+ export async function globalSetup() {
189
+ // The XDG Base Directory specification: an unset or empty XDG_STATE_HOME
190
+ // means ~/.local/state.
191
+ const root = join(process.env.XDG_STATE_HOME || join(homedir(), '.local', 'state'), 'zukhruf-testing', 'docker-runs');
192
+ await mkdir(root, { recursive: true });
193
+ const host = await DockerHost.resolve(undefined);
194
+ await recover(root, host);
195
+ const run = {
196
+ id: randomUUID(),
197
+ endpoint: host.endpoint,
198
+ pid: process.pid,
199
+ };
200
+ const directory = join(root, run.id);
201
+ await mkdir(directory);
202
+ const pending = join(directory, 'run.pending.json');
203
+ await writeFile(pending, JSON.stringify(run));
204
+ await rename(pending, join(directory, 'run.json'));
205
+ process.env[TEST_RUN_ID] = run.id;
206
+ process.env[TEST_RUN_DIRECTORY] = directory;
207
+ process.env.DOCKER_HOST = host.endpoint;
208
+ delete process.env.DOCKER_CONTEXT;
209
+ }
210
+ /** Synchronous, like cleanup, so that `--test-force-exit` cannot cut it off. */
211
+ export function globalTeardown() {
212
+ const owner = TestRun.fromEnvironment(process.env);
213
+ if (!owner)
214
+ throw new Error(`The Docker global teardown runs after its global setup, which sets ${TEST_RUN_ID} and ${TEST_RUN_DIRECTORY}`);
215
+ try {
216
+ const run = JSON.parse(readFileSync(join(owner.directory, 'run.json'), 'utf8'));
217
+ const processes = recordedProcesses(owner.directory);
218
+ // No test process recorded itself, so the run created nothing.
219
+ if (processes.length > 0)
220
+ cleanup(new DockerHost(run.endpoint, undefined), run, owner.directory);
221
+ // A process that still lives can still create something: the next run's
222
+ // recovery sweeps again once it has ended.
223
+ if (!processes.some(alive))
224
+ rmSync(owner.directory, { recursive: true, force: true });
225
+ }
226
+ catch (error) {
227
+ // Node sets exit code 1 for a teardown that throws, but prints nothing.
228
+ console.error(`Docker test cleanup failed; retained ownership record for retry: ${owner.directory}`, error);
229
+ process.exitCode = 1;
230
+ }
231
+ }
232
+ //# sourceMappingURL=docker-global-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-global-setup.js","sourceRoot":"","sources":["../../src/scripts/docker-global-setup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zukhruf/testing",
3
- "version": "0.3.22",
4
- "description": "Disposable fixtures for integration tests: Docker containers and database servers, SQLite and DuckDB databases, HTTP servers and streams. A supervisor removes what a killed test run left behind.",
3
+ "version": "0.3.24",
4
+ "description": "Disposable fixtures for integration tests: Docker containers and database servers, SQLite and DuckDB databases, HTTP servers and streams. Node's global setup and global teardown remove what a killed test run left behind.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -24,9 +24,6 @@
24
24
  "disposable"
25
25
  ],
26
26
  "type": "module",
27
- "bin": {
28
- "zukhruf-docker-tests": "./dist/scripts/run-docker-tests.js"
29
- },
30
27
  "exports": {
31
28
  "./package.json": "./package.json",
32
29
  "./node": {
@@ -106,6 +103,12 @@
106
103
  "types": "./dist/streams/stream-harness.d.ts",
107
104
  "import": "./dist/streams/stream-harness.js",
108
105
  "default": "./dist/streams/stream-harness.js"
106
+ },
107
+ "./docker-global-setup": {
108
+ "@zukhruf/source": "./src/scripts/docker-global-setup.ts",
109
+ "types": "./dist/scripts/docker-global-setup.d.ts",
110
+ "import": "./dist/scripts/docker-global-setup.js",
111
+ "default": "./dist/scripts/docker-global-setup.js"
109
112
  }
110
113
  },
111
114
  "files": [
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=run-docker-tests.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run-docker-tests.d.ts","sourceRoot":"","sources":["../../src/scripts/run-docker-tests.ts"],"names":[],"mappings":""}
@@ -1,227 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * zukhruf-docker-tests: runs `node --test` with this command's arguments as one
4
- * supervised run. Its test processes tie what they create to the run (see
5
- * TestRun.fromEnvironment), and this process removes it after they exit. A
6
- * run that was killed before it could is removed by the next run on the same
7
- * engine, from any project of this user.
8
- */
9
- import { spawn } from 'node:child_process';
10
- import { randomUUID } from 'node:crypto';
11
- import { mkdir, readFile, readdir, rename, rm, writeFile, } from 'node:fs/promises';
12
- import { homedir } from 'node:os';
13
- import { join } from 'node:path';
14
- import { setTimeout as delay } from 'node:timers/promises';
15
- import { SubprocessError } from 'nano-spawn';
16
- import { SHARED_SERVER_LABEL } from "../docker/docker.js";
17
- import { DockerHost, quote } from "../docker/host.js";
18
- import { TEST_RUN_DIRECTORY, TEST_RUN_ID, TEST_RUN_LABEL, TestRun, directoryPrefix, forwardPrefix, } from "../docker/test-run.js";
19
- if (process.platform === 'win32')
20
- throw new Error('zukhruf-docker-tests stops a run as one process group, which Windows does not have');
21
- const root = join(process.env.XDG_STATE_HOME || join(homedir(), '.local', 'state'), 'zukhruf-testing', 'docker-runs');
22
- const codeOf = (error) => error instanceof Error && 'code' in error ? error.code : undefined;
23
- function alive(pid) {
24
- if (!pid)
25
- return false;
26
- try {
27
- process.kill(pid, 0);
28
- return true;
29
- }
30
- catch (error) {
31
- return codeOf(error) !== 'ESRCH';
32
- }
33
- }
34
- /** Ignores Docker's answer that `missing` names something already gone. */
35
- const unlessMissing = (missing) => (error) => {
36
- if (!(error instanceof SubprocessError) || !missing.test(error.stderr))
37
- throw error;
38
- };
39
- async function readRecordedPath(file) {
40
- const { path } = JSON.parse(await readFile(file, 'utf8'));
41
- return path;
42
- }
43
- async function cleanup(host, run, directory, release) {
44
- const owner = new TestRun(run.id, directory);
45
- // Labels are attached atomically at creation. Never prune a daemon, remove
46
- // shared servers, or trust names alone as proof of ownership.
47
- const filter = ['--filter', `label=${TEST_RUN_LABEL}=${run.id}`];
48
- const { stdout: containers } = await host.command(['ps', '-aq', ...filter]);
49
- for (const id of containers.split('\n').filter(Boolean)) {
50
- await host
51
- .command([
52
- 'inspect',
53
- '--format',
54
- `{{index .Config.Labels "${SHARED_SERVER_LABEL}"}}`,
55
- id,
56
- ])
57
- .then(async ({ stdout: shared }) => {
58
- if (shared !== '1')
59
- await host.command(['rm', '--force', '--volumes', id]);
60
- })
61
- .catch(unlessMissing(/No such (object|container)/i));
62
- }
63
- const { stdout: volumes } = await host.command([
64
- 'volume',
65
- 'ls',
66
- '-q',
67
- ...filter,
68
- ]);
69
- for (const name of volumes.split('\n').filter(Boolean)) {
70
- await host
71
- .command(['volume', 'rm', name])
72
- .catch(unlessMissing(/no such volume|volume \S+ not found/i));
73
- }
74
- for (const file of await readdir(directory)) {
75
- if (file.startsWith('forward-')) {
76
- const path = await readRecordedPath(join(directory, file));
77
- if (!path.startsWith(forwardPrefix(owner)) || path.slice(5).includes('/'))
78
- throw new Error(`Invalid SSH forwarding cleanup record: ${path}`);
79
- await rm(path, { recursive: true, force: true });
80
- }
81
- else if (file.startsWith('directory-')) {
82
- const path = await readRecordedPath(join(directory, file));
83
- if (!path.includes(`/${directoryPrefix(owner)}`) || path.includes('/../'))
84
- throw new Error(`Invalid fixture cleanup record: ${path}`);
85
- if (host.remote)
86
- await host.shell(`rm -rf -- ${quote(path)}`);
87
- else
88
- await rm(path, { recursive: true, force: true });
89
- }
90
- }
91
- if (release)
92
- await rm(directory, { recursive: true, force: true });
93
- }
94
- async function readRun(directory) {
95
- try {
96
- return JSON.parse(await readFile(join(directory, 'run.json'), 'utf8'));
97
- }
98
- catch {
99
- // Its supervisor may still be writing it, or another one just claimed it.
100
- return undefined;
101
- }
102
- }
103
- /** Removes what dead runs on this engine left behind. */
104
- async function recover(host) {
105
- for (const name of await readdir(root)) {
106
- // A claim names its supervisor: while it lives, the run is being recovered.
107
- const claimant = /^recovering-(\d+)-/.exec(name)?.[1];
108
- if (claimant !== undefined && alive(Number(claimant)))
109
- continue;
110
- const directory = join(root, name);
111
- const previous = await readRun(directory);
112
- if (!previous ||
113
- previous.endpoint !== host.endpoint ||
114
- alive(previous.pid) ||
115
- alive(previous.childPid) ||
116
- (previous.childPid !== undefined && alive(-previous.childPid)))
117
- continue;
118
- // Supervisors start in parallel; the rename lets exactly one recover a run.
119
- const claimed = join(root, `recovering-${process.pid}-${randomUUID()}`);
120
- try {
121
- await rename(directory, claimed);
122
- }
123
- catch (error) {
124
- if (codeOf(error) === 'ENOENT')
125
- continue;
126
- throw error;
127
- }
128
- try {
129
- await cleanup(host, previous, claimed, true);
130
- }
131
- catch (error) {
132
- throw new Error(`Could not recover Docker test resources. Retained ownership record: ${claimed}`, { cause: error });
133
- }
134
- }
135
- }
136
- await mkdir(root, { recursive: true });
137
- const host = await DockerHost.resolve();
138
- await recover(host);
139
- const run = {
140
- id: randomUUID(),
141
- endpoint: host.endpoint,
142
- pid: process.pid,
143
- };
144
- const directory = join(root, run.id);
145
- await mkdir(directory);
146
- const record = async (current) => {
147
- const pending = join(directory, 'run.pending.json');
148
- await writeFile(pending, JSON.stringify(current));
149
- await rename(pending, join(directory, 'run.json'));
150
- };
151
- await record(run);
152
- const args = process.argv.slice(2);
153
- const concurrency = host.remote && !args.some((arg) => arg.startsWith('--test-concurrency'))
154
- ? ['--test-concurrency=1']
155
- : [];
156
- const child = spawn(process.execPath, ['--test', ...concurrency, ...args], {
157
- stdio: 'inherit',
158
- detached: true,
159
- env: {
160
- ...process.env,
161
- DOCKER_CONTEXT: undefined,
162
- DOCKER_HOST: host.endpoint,
163
- [TEST_RUN_ID]: run.id,
164
- [TEST_RUN_DIRECTORY]: directory,
165
- },
166
- });
167
- const exited = new Promise((resolve, reject) => {
168
- child.once('error', reject);
169
- child.once('exit', (code) => resolve(code ?? 1));
170
- });
171
- /** Signals the run's process group; false when the group could not be stopped. */
172
- async function kill(signal, attempt = 0) {
173
- if (!child.pid)
174
- return true;
175
- try {
176
- process.kill(-child.pid, signal);
177
- return true;
178
- }
179
- catch (error) {
180
- if (codeOf(error) === 'ESRCH')
181
- return true;
182
- // macOS can briefly report EPERM while an empty group is being reaped.
183
- // Retry that transition; a persistent denial must retain ownership.
184
- if (codeOf(error) === 'EPERM' && attempt < 3) {
185
- await delay(25);
186
- return kill(signal, attempt + 1);
187
- }
188
- console.error(`Could not signal Docker test process group ${child.pid}:`, error);
189
- child.kill(signal);
190
- return false;
191
- }
192
- }
193
- const finished = new AbortController();
194
- const interruption = new AbortController();
195
- const interrupt = () => {
196
- if (interruption.signal.aborted)
197
- return;
198
- interruption.abort();
199
- void kill('SIGTERM');
200
- void delay(5_000, undefined, { signal: finished.signal }).then(() => kill('SIGKILL'), () => { });
201
- };
202
- process.on('SIGINT', interrupt);
203
- process.on('SIGTERM', interrupt);
204
- try {
205
- await record({ ...run, childPid: child.pid });
206
- const code = await exited;
207
- process.exitCode = interruption.signal.aborted ? 130 : code;
208
- }
209
- finally {
210
- finished.abort();
211
- // Includes SSH channels in workers killed by node --test or --test-force-exit.
212
- const stopped = await kill('SIGKILL');
213
- try {
214
- await cleanup(host, run, directory, stopped);
215
- if (!stopped) {
216
- process.exitCode = 1;
217
- console.error(`Docker test termination failed; retained ownership record for retry: ${directory}`);
218
- }
219
- }
220
- catch (error) {
221
- process.exitCode = 1;
222
- console.error(`Docker test cleanup failed; retained ownership record for retry: ${directory}`, error);
223
- }
224
- process.off('SIGINT', interrupt);
225
- process.off('SIGTERM', interrupt);
226
- }
227
- //# sourceMappingURL=run-docker-tests.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run-docker-tests.js","sourceRoot":"","sources":["../../src/scripts/run-docker-tests.ts"],"names":[],"mappings":"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"}