@owlmeans/test-integration 0.1.18-rc.30 → 0.1.18-rc.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,7 +19,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
19
19
  your project's skill store (`.agents/skills/`):
20
20
 
21
21
  ```sh
22
- npx @owlmeans/agent-skills@^0.1.18-rc.42
22
+ npx @owlmeans/agent-skills@^0.1.18-rc.48
23
23
  ```
24
24
 
25
25
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/test-integration",
4
- "version": "0.1.18-rc.30",
5
- "generatedAt": "2026-09-29T08:01:58.123Z",
4
+ "version": "0.1.18-rc.32",
5
+ "generatedAt": "2026-10-05T08:32:19.106Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -6,7 +6,7 @@ description: Category-C integration tests for OwlMeans Common packages that talk
6
6
 
7
7
  # Integration Tests — Category C
8
8
 
9
- **Install:** `"@owlmeans/test-integration": "^0.1.18-rc.30"` in `devDependencies`
9
+ **Install:** `"@owlmeans/test-integration": "^0.1.18-rc.32"` in `devDependencies`
10
10
 
11
11
  Category C applies to packages that integrate with external services: `postgres`,
12
12
  `postgres-resource`, `mongo`, `mongo-resource`, `redis`, `redis-resource`, `redis-queue`,
@@ -1,4 +1,4 @@
1
- type CleanupFn = () => void | Promise<void>;
1
+ import type { CleanupFn } from './types.local.js';
2
2
  /**
3
3
  * Register a cleanup function that `runCleanups()` will execute (LIFO).
4
4
  * Use from `tests/context.ts` `setup()` to schedule teardown of resources
@@ -8,9 +8,8 @@ type CleanupFn = () => void | Promise<void>;
8
8
  export declare const registerCleanup: (fn: CleanupFn) => void;
9
9
  /**
10
10
  * Run all pending cleanup functions in reverse registration order.
11
- * Errors are swallowed and reported to stderr so a failing cleanup
11
+ * Errors are swallowed and logged as warnings so a failing cleanup
12
12
  * cannot mask a test failure.
13
13
  */
14
14
  export declare const runCleanups: () => Promise<void>;
15
- export {};
16
15
  //# sourceMappingURL=cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAI3C;;;;;GAKG;AACH,eAAO,MAAM,eAAe,OAAQ,SAAS,KAAG,IAE/C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,IAAI,CAUhD,CAAA"}
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMjD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,OAAQ,SAAS,KAAG,IAE/C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,IAAI,CAUhD,CAAA"}
package/build/cleanup.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { logger } from '@owlmeans/log';
2
+ const log = logger('test-integration');
1
3
  const queue = [];
2
4
  /**
3
5
  * Register a cleanup function that `runCleanups()` will execute (LIFO).
@@ -10,7 +12,7 @@ export const registerCleanup = (fn) => {
10
12
  };
11
13
  /**
12
14
  * Run all pending cleanup functions in reverse registration order.
13
- * Errors are swallowed and reported to stderr so a failing cleanup
15
+ * Errors are swallowed and logged as warnings so a failing cleanup
14
16
  * cannot mask a test failure.
15
17
  */
16
18
  export const runCleanups = async () => {
@@ -22,7 +24,7 @@ export const runCleanups = async () => {
22
24
  await fn();
23
25
  }
24
26
  catch (err) {
25
- console.error('@owlmeans/test-integration cleanup failed:', err);
27
+ log.warn('Cleanup failed', err);
26
28
  }
27
29
  }
28
30
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAgB,EAAE,CAAA;AAE7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAa,EAAQ,EAAE;IACrD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAChB,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;IACnD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,EAAE,IAAI,IAAI;YAAE,SAAQ;QACxB,IAAI,CAAC;YACH,MAAM,EAAE,EAAE,CAAA;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,GAAG,CAAC,CAAA;QAClE,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../src/cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAGtC,MAAM,GAAG,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAA;AAEtC,MAAM,KAAK,GAAgB,EAAE,CAAA;AAE7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAa,EAAQ,EAAE;IACrD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAChB,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;IACnD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,EAAE,IAAI,IAAI;YAAE,SAAQ;QACxB,IAAI,CAAC;YACH,MAAM,EAAE,EAAE,CAAA;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ /** How long one connect may take before the address counts as unreachable. */
2
+ export declare const CONNECT_TIMEOUT_MS = 1500;
3
+ /** The probe runs in a child process; this covers its own startup on a loaded machine. */
4
+ export declare const SPAWN_GRACE_MS = 5000;
5
+ export declare const PROBE_SCRIPT = "\nconst net = require('net')\nconst [targets, timeout] = JSON.parse(process.env.OWLMEANS_TEST_PROBE)\nlet pending = targets.length\nlet last = ''\nfor (const target of targets) {\n let settled = false\n const socket = net.connect({ host: target.host, port: target.port })\n const fail = code => {\n if (settled) return\n settled = true\n socket.destroy()\n last = code\n if (--pending === 0) { process.stdout.write(last); process.exit(1) }\n }\n socket.setTimeout(timeout)\n socket.once('connect', () => process.exit(0))\n socket.once('timeout', () => fail('ETIMEDOUT'))\n socket.once('error', error => fail(error.code || String(error)))\n}\n";
6
+ //# sourceMappingURL=consts.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../src/consts.local.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AAEvC,0FAA0F;AAC1F,eAAO,MAAM,cAAc,OAAQ,CAAA;AAInC,eAAO,MAAM,YAAY,8pBAoBxB,CAAA"}
@@ -0,0 +1,28 @@
1
+ /** How long one connect may take before the address counts as unreachable. */
2
+ export const CONNECT_TIMEOUT_MS = 1_500;
3
+ /** The probe runs in a child process; this covers its own startup on a loaded machine. */
4
+ export const SPAWN_GRACE_MS = 5_000;
5
+ // Runs under whichever runtime runs the suite (`process.execPath`), so it is plain CommonJS
6
+ // that both `bun -e` and `node -e` evaluate.
7
+ export const PROBE_SCRIPT = `
8
+ const net = require('net')
9
+ const [targets, timeout] = JSON.parse(process.env.OWLMEANS_TEST_PROBE)
10
+ let pending = targets.length
11
+ let last = ''
12
+ for (const target of targets) {
13
+ let settled = false
14
+ const socket = net.connect({ host: target.host, port: target.port })
15
+ const fail = code => {
16
+ if (settled) return
17
+ settled = true
18
+ socket.destroy()
19
+ last = code
20
+ if (--pending === 0) { process.stdout.write(last); process.exit(1) }
21
+ }
22
+ socket.setTimeout(timeout)
23
+ socket.once('connect', () => process.exit(0))
24
+ socket.once('timeout', () => fail('ETIMEDOUT'))
25
+ socket.once('error', error => fail(error.code || String(error)))
26
+ }
27
+ `;
28
+ //# sourceMappingURL=consts.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../src/consts.local.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAEvC,0FAA0F;AAC1F,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAEnC,4FAA4F;AAC5F,6CAA6C;AAC7C,MAAM,CAAC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;CAoB3B,CAAA"}
package/build/gates.d.ts CHANGED
@@ -1,45 +1,8 @@
1
- export interface IntegrationGate<E> {
2
- skip: boolean;
3
- reason?: string;
4
- env: Partial<E>;
5
- }
6
- export interface MongoEnv {
7
- MONGO_URL: string;
8
- MONGO_TEST_DB_PREFIX: string;
9
- }
1
+ import type { IntegrationGate, KubeEnv, MongoEnv, PostgresEnv, RedisEnv, S3Env, SmtpEnv } from './types.js';
10
2
  export declare const mongoGate: () => IntegrationGate<MongoEnv>;
11
- export interface RedisEnv {
12
- REDIS_URL: string;
13
- REDIS_TEST_KEY_PREFIX: string;
14
- }
15
3
  export declare const redisGate: () => IntegrationGate<RedisEnv>;
16
- export interface S3Env {
17
- S3_ENDPOINT: string;
18
- S3_KEY: string;
19
- S3_SECRET: string;
20
- S3_TEST_BUCKET: string;
21
- S3_REGION: string;
22
- }
23
4
  export declare const s3Gate: () => IntegrationGate<S3Env>;
24
- export interface KubeEnv {
25
- KUBE_CONFIG: string;
26
- KUBE_TEST_OK: string;
27
- }
28
5
  export declare const kubeGate: () => IntegrationGate<KubeEnv>;
29
- export interface PostgresEnv {
30
- POSTGRES_URL: string;
31
- POSTGRES_TEST_DB_PREFIX: string;
32
- }
33
6
  export declare const postgresGate: () => IntegrationGate<PostgresEnv>;
34
- export interface SmtpEnv {
35
- SMTP_HOST: string;
36
- SMTP_PORT: string;
37
- SMTP_SECURE: string;
38
- SMTP_USER: string;
39
- SMTP_PASSWORD: string;
40
- SMTP_FROM: string;
41
- /** Mailbox the specs deliver to. Required — these tests send real mail. */
42
- SMTP_TEST_TO: string;
43
- }
44
7
  export declare const smtpGate: () => IntegrationGate<SmtpEnv>;
45
8
  //# sourceMappingURL=gates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAChB;AAqCD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED,eAAO,MAAM,SAAS,QAAO,eAAe,CAAC,QAAQ,CAC2D,CAAA;AAEhH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,EAAE,MAAM,CAAA;CAC9B;AAED,eAAO,MAAM,SAAS,QAAO,eAAe,CAAC,QAAQ,CAC2D,CAAA;AAEhH,MAAM,WAAW,KAAK;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,MAAM,QAAO,eAAe,CAAC,KAAK,CAI5C,CAAA;AAEH,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,eAAO,MAAM,QAAQ,QAAO,eAAe,CAAC,OAAO,CACU,CAAA;AAE7D,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,uBAAuB,EAAE,MAAM,CAAA;CAChC;AAED,eAAO,MAAM,YAAY,QAAO,eAAe,CAAC,WAAW,CACgE,CAAA;AAE3H,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,eAAO,MAAM,QAAQ,QAAO,eAAe,CAAC,OAAO,CAIhD,CAAA"}
1
+ {"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAyB3G,eAAO,MAAM,SAAS,QAAO,eAAe,CAAC,QAAQ,CAC2D,CAAA;AAEhH,eAAO,MAAM,SAAS,QAAO,eAAe,CAAC,QAAQ,CAC2D,CAAA;AAEhH,eAAO,MAAM,MAAM,QAAO,eAAe,CAAC,KAAK,CAI5C,CAAA;AAEH,eAAO,MAAM,QAAQ,QAAO,eAAe,CAAC,OAAO,CACU,CAAA;AAE7D,eAAO,MAAM,YAAY,QAAO,eAAe,CAAC,WAAW,CACgE,CAAA;AAE3H,eAAO,MAAM,QAAQ,QAAO,eAAe,CAAC,OAAO,CAIhD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAQrD,MAAM,OAAO,GAAG,CAAI,IAA0B,EAAc,EAAE;IAC5D,MAAM,GAAG,GAA2B,EAAE,CAAA;IACtC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,MAAM,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAW,CAAA;IAClD,CAAC;IACD,OAAO,GAAiB,CAAA;AAC1B,CAAC,CAAA;AAcD,MAAM,iBAAiB,GAAG,CACxB,QAA8B,EAC9B,QAAQ,GAAyB,EAAE,EACnC,SAAwB,EACJ,EAAE;IACtB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;IACjC,MAAM,GAAG,GAAG,OAAO,CAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAA;IAClD,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAA;IACpE,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAW,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;QAC5G,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;IACxD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;AAC7B,CAAC,CAAA;AAOD,MAAM,CAAC,MAAM,SAAS,GAAG,GAA8B,EAAE,CACvD,iBAAiB,CAAW,CAAC,WAAW,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAA;AAOhH,MAAM,CAAC,MAAM,SAAS,GAAG,GAA8B,EAAE,CACvD,iBAAiB,CAAW,CAAC,WAAW,CAAC,EAAE,CAAC,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAUhH,MAAM,CAAC,MAAM,MAAM,GAAG,GAA2B,EAAE,CACjD,iBAAiB,CACf,CAAC,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,CAAC,EACxD,CAAC,WAAW,CAAC,CACd,CAAA;AAOH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA6B,EAAE,CACrD,iBAAiB,CAAU,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAA;AAO7D,MAAM,CAAC,MAAM,YAAY,GAAG,GAAiC,EAAE,CAC7D,iBAAiB,CAAc,CAAC,cAAc,CAAC,EAAE,CAAC,yBAAyB,CAAC,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAa3H,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA6B,EAAE,CACrD,iBAAiB,CACf,CAAC,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,CAAC,EACxE,CAAC,WAAW,EAAE,aAAa,CAAC,CAC7B,CAAA"}
1
+ {"version":3,"file":"gates.js","sourceRoot":"","sources":["../src/gates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAIrD,MAAM,OAAO,GAAG,CAAI,IAA0B,EAAc,EAAE;IAC5D,MAAM,GAAG,GAA2B,EAAE,CAAA;IACtC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,MAAM,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAW,CAAA;IAClD,CAAC;IACD,OAAO,GAAiB,CAAA;AAC1B,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CACxB,QAA8B,EAC9B,QAAQ,GAAyB,EAAE,EACnC,SAAwB,EACJ,EAAE;IACtB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;IACjC,MAAM,GAAG,GAAG,OAAO,CAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAA;IAClD,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAA;IACpE,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAW,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;QAC5G,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;IACxD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAA;AAC7B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,GAA8B,EAAE,CACvD,iBAAiB,CAAW,CAAC,WAAW,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAA;AAEhH,MAAM,CAAC,MAAM,SAAS,GAAG,GAA8B,EAAE,CACvD,iBAAiB,CAAW,CAAC,WAAW,CAAC,EAAE,CAAC,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAEhH,MAAM,CAAC,MAAM,MAAM,GAAG,GAA2B,EAAE,CACjD,iBAAiB,CACf,CAAC,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,CAAC,EACxD,CAAC,WAAW,CAAC,CACd,CAAA;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA6B,EAAE,CACrD,iBAAiB,CAAU,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAA;AAE7D,MAAM,CAAC,MAAM,YAAY,GAAG,GAAiC,EAAE,CAC7D,iBAAiB,CAAc,CAAC,cAAc,CAAC,EAAE,CAAC,yBAAyB,CAAC,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAE3H,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA6B,EAAE,CACrD,iBAAiB,CACf,CAAC,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,CAAC,EACxE,CAAC,WAAW,EAAE,aAAa,CAAC,CAC7B,CAAA"}
package/build/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './gates.js';
2
+ export type * from './types.js';
2
3
  export * from './naming.js';
3
4
  export * from './cleanup.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -1,16 +1,4 @@
1
- /**
2
- * Whether the server a connection string names answers at all — asked synchronously, because
3
- * Bun decides `test` vs `test.skip` synchronously and every gate is read at module scope.
4
- *
5
- * A populated variable says where the service should be, not that it is there: a developer's
6
- * `.env` keeps the port-forward address long after the forward is gone, and a suite that trusts
7
- * it spends its whole `beforeAll` budget on a refused connection and FAILS. Only a TCP connect is
8
- * asked — never a login — so no driver is needed here and no credential leaves the variable.
9
- */
10
- export interface ProbeTarget {
11
- host: string;
12
- port: number;
13
- }
1
+ import type { ProbeTarget } from './types.js';
14
2
  /**
15
3
  * Every `host:port` in the authority of a connection string, or `null` when the string names
16
4
  * nothing a TCP connect can check — an SRV record, a unix socket, or a shape this cannot read.
@@ -1 +1 @@
1
- {"version":3,"file":"reachability.d.ts","sourceRoot":"","sources":["../src/reachability.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAWD;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,eAAe,MAAM,KAAG,WAAW,EAAE,GAAG,IA6B/E,CAAA;AA0BD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YAAa,WAAW,EAAE,KAAG,MAAM,GAAG,IAkB9D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAAc,MAAM,OAAO,MAAM,eAAe,MAAM,KAAG,MAAM,GAAG,IAiB/F,CAAA"}
1
+ {"version":3,"file":"reachability.d.ts","sourceRoot":"","sources":["../src/reachability.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAiB7C;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,eAAe,MAAM,KAAG,WAAW,EAAE,GAAG,IA6B/E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,YAAa,WAAW,EAAE,KAAG,MAAM,GAAG,IAkB9D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAAc,MAAM,OAAO,MAAM,eAAe,MAAM,KAAG,MAAM,GAAG,IAiB/F,CAAA"}
@@ -1,8 +1,16 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- /** How long one connect may take before the address counts as unreachable. */
3
- const CONNECT_TIMEOUT_MS = 1_500;
4
- /** The probe runs in a child process; this covers its own startup on a loaded machine. */
5
- const SPAWN_GRACE_MS = 5_000;
2
+ import { logger } from '@owlmeans/log';
3
+ import { CONNECT_TIMEOUT_MS, PROBE_SCRIPT, SPAWN_GRACE_MS } from './consts.local.js';
4
+ const log = logger('test-integration');
5
+ /**
6
+ * Whether the server a connection string names answers at all — asked synchronously, because
7
+ * Bun decides `test` vs `test.skip` synchronously and every gate is read at module scope.
8
+ *
9
+ * A populated variable says where the service should be, not that it is there: a developer's
10
+ * `.env` keeps the port-forward address long after the forward is gone, and a suite that trusts
11
+ * it spends its whole `beforeAll` budget on a refused connection and FAILS. Only a TCP connect is
12
+ * asked — never a login — so no driver is needed here and no credential leaves the variable.
13
+ */
6
14
  const answers = new Map();
7
15
  const warned = new Set();
8
16
  /**
@@ -39,29 +47,6 @@ export const parseTargets = (url, defaultPort) => {
39
47
  }
40
48
  return targets.length > 0 ? targets : null;
41
49
  };
42
- // Runs under whichever runtime runs the suite (`process.execPath`), so it is plain CommonJS
43
- // that both `bun -e` and `node -e` evaluate.
44
- const PROBE_SCRIPT = `
45
- const net = require('net')
46
- const [targets, timeout] = JSON.parse(process.env.OWLMEANS_TEST_PROBE)
47
- let pending = targets.length
48
- let last = ''
49
- for (const target of targets) {
50
- let settled = false
51
- const socket = net.connect({ host: target.host, port: target.port })
52
- const fail = code => {
53
- if (settled) return
54
- settled = true
55
- socket.destroy()
56
- last = code
57
- if (--pending === 0) { process.stdout.write(last); process.exit(1) }
58
- }
59
- socket.setTimeout(timeout)
60
- socket.once('connect', () => process.exit(0))
61
- socket.once('timeout', () => fail('ETIMEDOUT'))
62
- socket.once('error', error => fail(error.code || String(error)))
63
- }
64
- `;
65
50
  /**
66
51
  * `null` when at least one target accepts a TCP connection, otherwise the reason none did.
67
52
  *
@@ -102,7 +87,7 @@ export const unreachableReason = (variable, url, defaultPort) => {
102
87
  const reason = `${variable} is set, but ${unreachable} — start the service (or its port-forward) to run these specs`;
103
88
  if (!warned.has(reason)) {
104
89
  warned.add(reason);
105
- console.warn(`@owlmeans/test-integration: skipping — ${reason}`);
90
+ log.warn('Skipping integration specs: a configured service is unreachable', { variable, unreachable });
106
91
  }
107
92
  return reason;
108
93
  };
@@ -1 +1 @@
1
- {"version":3,"file":"reachability.js","sourceRoot":"","sources":["../src/reachability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reachability.js","sourceRoot":"","sources":["../src/reachability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export interface IntegrationGate<E> {
2
+ skip: boolean;
3
+ reason?: string;
4
+ env: Partial<E>;
5
+ }
6
+ export interface MongoEnv {
7
+ MONGO_URL: string;
8
+ MONGO_TEST_DB_PREFIX: string;
9
+ }
10
+ export interface RedisEnv {
11
+ REDIS_URL: string;
12
+ REDIS_TEST_KEY_PREFIX: string;
13
+ }
14
+ export interface S3Env {
15
+ S3_ENDPOINT: string;
16
+ S3_KEY: string;
17
+ S3_SECRET: string;
18
+ S3_TEST_BUCKET: string;
19
+ S3_REGION: string;
20
+ }
21
+ export interface KubeEnv {
22
+ KUBE_CONFIG: string;
23
+ KUBE_TEST_OK: string;
24
+ }
25
+ export interface PostgresEnv {
26
+ POSTGRES_URL: string;
27
+ POSTGRES_TEST_DB_PREFIX: string;
28
+ }
29
+ export interface SmtpEnv {
30
+ SMTP_HOST: string;
31
+ SMTP_PORT: string;
32
+ SMTP_SECURE: string;
33
+ SMTP_USER: string;
34
+ SMTP_PASSWORD: string;
35
+ SMTP_FROM: string;
36
+ /** Mailbox the specs deliver to. Required — these tests send real mail. */
37
+ SMTP_TEST_TO: string;
38
+ }
39
+ export interface ProbeTarget {
40
+ host: string;
41
+ port: number;
42
+ }
43
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,KAAK;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,uBAAuB,EAAE,MAAM,CAAA;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ export type CleanupFn = () => void | Promise<void>;
2
+ /**
3
+ * A connection-string variable whose server must answer a TCP connect for the gate to open.
4
+ *
5
+ * Only for a service a developer reaches through a local address that can go away — a
6
+ * port-forward, a container. A populated variable pointing at nothing then closes the gate with
7
+ * a printed reason instead of failing every suite behind it on a refused connection.
8
+ */
9
+ export interface Reachable<E> {
10
+ key: keyof E & string;
11
+ defaultPort: number;
12
+ }
13
+ //# sourceMappingURL=types.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAElD;;;;;;GAMG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/test-integration",
3
- "version": "0.1.18-rc.30",
3
+ "version": "0.1.18-rc.32",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -21,11 +21,12 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@owlmeans/test": "^0.1.18-rc.33"
24
+ "@owlmeans/log": "^0.1.18-rc.1",
25
+ "@owlmeans/test": "^0.1.18-rc.34"
25
26
  },
26
27
  "devDependencies": {
27
28
  "@owlmeans/dep-config": "^0.1.18-rc.6",
28
- "@types/bun": "^1.4.0",
29
+ "@types/bun": "^1.4.2",
29
30
  "nodemon": "^3.1.14",
30
31
  "typescript": "^7.0.2"
31
32
  },
package/src/cleanup.ts CHANGED
@@ -1,4 +1,7 @@
1
- type CleanupFn = () => void | Promise<void>
1
+ import { logger } from '@owlmeans/log'
2
+ import type { CleanupFn } from './types.local.js'
3
+
4
+ const log = logger('test-integration')
2
5
 
3
6
  const queue: CleanupFn[] = []
4
7
 
@@ -14,7 +17,7 @@ export const registerCleanup = (fn: CleanupFn): void => {
14
17
 
15
18
  /**
16
19
  * Run all pending cleanup functions in reverse registration order.
17
- * Errors are swallowed and reported to stderr so a failing cleanup
20
+ * Errors are swallowed and logged as warnings so a failing cleanup
18
21
  * cannot mask a test failure.
19
22
  */
20
23
  export const runCleanups = async (): Promise<void> => {
@@ -24,7 +27,7 @@ export const runCleanups = async (): Promise<void> => {
24
27
  try {
25
28
  await fn()
26
29
  } catch (err) {
27
- console.error('@owlmeans/test-integration cleanup failed:', err)
30
+ log.warn('Cleanup failed', err)
28
31
  }
29
32
  }
30
33
  }
@@ -0,0 +1,29 @@
1
+ /** How long one connect may take before the address counts as unreachable. */
2
+ export const CONNECT_TIMEOUT_MS = 1_500
3
+
4
+ /** The probe runs in a child process; this covers its own startup on a loaded machine. */
5
+ export const SPAWN_GRACE_MS = 5_000
6
+
7
+ // Runs under whichever runtime runs the suite (`process.execPath`), so it is plain CommonJS
8
+ // that both `bun -e` and `node -e` evaluate.
9
+ export const PROBE_SCRIPT = `
10
+ const net = require('net')
11
+ const [targets, timeout] = JSON.parse(process.env.OWLMEANS_TEST_PROBE)
12
+ let pending = targets.length
13
+ let last = ''
14
+ for (const target of targets) {
15
+ let settled = false
16
+ const socket = net.connect({ host: target.host, port: target.port })
17
+ const fail = code => {
18
+ if (settled) return
19
+ settled = true
20
+ socket.destroy()
21
+ last = code
22
+ if (--pending === 0) { process.stdout.write(last); process.exit(1) }
23
+ }
24
+ socket.setTimeout(timeout)
25
+ socket.once('connect', () => process.exit(0))
26
+ socket.once('timeout', () => fail('ETIMEDOUT'))
27
+ socket.once('error', error => fail(error.code || String(error)))
28
+ }
29
+ `
package/src/gates.ts CHANGED
@@ -1,11 +1,7 @@
1
1
  import { hasEnv, requireEnv } from '@owlmeans/test'
2
2
  import { unreachableReason } from './reachability.js'
3
-
4
- export interface IntegrationGate<E> {
5
- skip: boolean
6
- reason?: string
7
- env: Partial<E>
8
- }
3
+ import type { Reachable } from './types.local.js'
4
+ import type { IntegrationGate, KubeEnv, MongoEnv, PostgresEnv, RedisEnv, S3Env, SmtpEnv } from './types.js'
9
5
 
10
6
  const collect = <E>(keys: (keyof E & string)[]): Partial<E> => {
11
7
  const env: Record<string, string> = {}
@@ -15,18 +11,6 @@ const collect = <E>(keys: (keyof E & string)[]): Partial<E> => {
15
11
  return env as Partial<E>
16
12
  }
17
13
 
18
- /**
19
- * A connection-string variable whose server must answer a TCP connect for the gate to open.
20
- *
21
- * Only for a service a developer reaches through a local address that can go away — a
22
- * port-forward, a container. A populated variable pointing at nothing then closes the gate with
23
- * a printed reason instead of failing every suite behind it on a refused connection.
24
- */
25
- interface Reachable<E> {
26
- key: keyof E & string
27
- defaultPort: number
28
- }
29
-
30
14
  const toIntegrationGate = <E>(
31
15
  required: (keyof E & string)[],
32
16
  optional: (keyof E & string)[] = [],
@@ -42,63 +26,24 @@ const toIntegrationGate = <E>(
42
26
  return { skip: false, env }
43
27
  }
44
28
 
45
- export interface MongoEnv {
46
- MONGO_URL: string
47
- MONGO_TEST_DB_PREFIX: string
48
- }
49
-
50
29
  export const mongoGate = (): IntegrationGate<MongoEnv> =>
51
30
  toIntegrationGate<MongoEnv>(['MONGO_URL'], ['MONGO_TEST_DB_PREFIX'], { key: 'MONGO_URL', defaultPort: 27017 })
52
31
 
53
- export interface RedisEnv {
54
- REDIS_URL: string
55
- REDIS_TEST_KEY_PREFIX: string
56
- }
57
-
58
32
  export const redisGate = (): IntegrationGate<RedisEnv> =>
59
33
  toIntegrationGate<RedisEnv>(['REDIS_URL'], ['REDIS_TEST_KEY_PREFIX'], { key: 'REDIS_URL', defaultPort: 6379 })
60
34
 
61
- export interface S3Env {
62
- S3_ENDPOINT: string
63
- S3_KEY: string
64
- S3_SECRET: string
65
- S3_TEST_BUCKET: string
66
- S3_REGION: string
67
- }
68
-
69
35
  export const s3Gate = (): IntegrationGate<S3Env> =>
70
36
  toIntegrationGate<S3Env>(
71
37
  ['S3_ENDPOINT', 'S3_KEY', 'S3_SECRET', 'S3_TEST_BUCKET'],
72
38
  ['S3_REGION']
73
39
  )
74
40
 
75
- export interface KubeEnv {
76
- KUBE_CONFIG: string
77
- KUBE_TEST_OK: string
78
- }
79
-
80
41
  export const kubeGate = (): IntegrationGate<KubeEnv> =>
81
42
  toIntegrationGate<KubeEnv>(['KUBE_CONFIG', 'KUBE_TEST_OK'])
82
43
 
83
- export interface PostgresEnv {
84
- POSTGRES_URL: string
85
- POSTGRES_TEST_DB_PREFIX: string
86
- }
87
-
88
44
  export const postgresGate = (): IntegrationGate<PostgresEnv> =>
89
45
  toIntegrationGate<PostgresEnv>(['POSTGRES_URL'], ['POSTGRES_TEST_DB_PREFIX'], { key: 'POSTGRES_URL', defaultPort: 5432 })
90
46
 
91
- export interface SmtpEnv {
92
- SMTP_HOST: string
93
- SMTP_PORT: string
94
- SMTP_SECURE: string
95
- SMTP_USER: string
96
- SMTP_PASSWORD: string
97
- SMTP_FROM: string
98
- /** Mailbox the specs deliver to. Required — these tests send real mail. */
99
- SMTP_TEST_TO: string
100
- }
101
-
102
47
  export const smtpGate = (): IntegrationGate<SmtpEnv> =>
103
48
  toIntegrationGate<SmtpEnv>(
104
49
  ['SMTP_HOST', 'SMTP_USER', 'SMTP_PASSWORD', 'SMTP_FROM', 'SMTP_TEST_TO'],
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './gates.js'
2
+ export type * from './types.js'
2
3
  export * from './naming.js'
3
4
  export * from './cleanup.js'
@@ -1,4 +1,9 @@
1
1
  import { spawnSync } from 'node:child_process'
2
+ import { logger } from '@owlmeans/log'
3
+ import { CONNECT_TIMEOUT_MS, PROBE_SCRIPT, SPAWN_GRACE_MS } from './consts.local.js'
4
+ import type { ProbeTarget } from './types.js'
5
+
6
+ const log = logger('test-integration')
2
7
 
3
8
  /**
4
9
  * Whether the server a connection string names answers at all — asked synchronously, because
@@ -10,17 +15,6 @@ import { spawnSync } from 'node:child_process'
10
15
  * asked — never a login — so no driver is needed here and no credential leaves the variable.
11
16
  */
12
17
 
13
- export interface ProbeTarget {
14
- host: string
15
- port: number
16
- }
17
-
18
- /** How long one connect may take before the address counts as unreachable. */
19
- const CONNECT_TIMEOUT_MS = 1_500
20
-
21
- /** The probe runs in a child process; this covers its own startup on a loaded machine. */
22
- const SPAWN_GRACE_MS = 5_000
23
-
24
18
  const answers = new Map<string, string | null>()
25
19
  const warned = new Set<string>()
26
20
 
@@ -60,30 +54,6 @@ export const parseTargets = (url: string, defaultPort: number): ProbeTarget[] |
60
54
  return targets.length > 0 ? targets : null
61
55
  }
62
56
 
63
- // Runs under whichever runtime runs the suite (`process.execPath`), so it is plain CommonJS
64
- // that both `bun -e` and `node -e` evaluate.
65
- const PROBE_SCRIPT = `
66
- const net = require('net')
67
- const [targets, timeout] = JSON.parse(process.env.OWLMEANS_TEST_PROBE)
68
- let pending = targets.length
69
- let last = ''
70
- for (const target of targets) {
71
- let settled = false
72
- const socket = net.connect({ host: target.host, port: target.port })
73
- const fail = code => {
74
- if (settled) return
75
- settled = true
76
- socket.destroy()
77
- last = code
78
- if (--pending === 0) { process.stdout.write(last); process.exit(1) }
79
- }
80
- socket.setTimeout(timeout)
81
- socket.once('connect', () => process.exit(0))
82
- socket.once('timeout', () => fail('ETIMEDOUT'))
83
- socket.once('error', error => fail(error.code || String(error)))
84
- }
85
- `
86
-
87
57
  /**
88
58
  * `null` when at least one target accepts a TCP connection, otherwise the reason none did.
89
59
  *
@@ -128,7 +98,7 @@ export const unreachableReason = (variable: string, url: string, defaultPort: nu
128
98
  const reason = `${variable} is set, but ${unreachable} — start the service (or its port-forward) to run these specs`
129
99
  if (!warned.has(reason)) {
130
100
  warned.add(reason)
131
- console.warn(`@owlmeans/test-integration: skipping — ${reason}`)
101
+ log.warn('Skipping integration specs: a configured service is unreachable', { variable, unreachable })
132
102
  }
133
103
 
134
104
  return reason
@@ -0,0 +1,13 @@
1
+ export type CleanupFn = () => void | Promise<void>
2
+
3
+ /**
4
+ * A connection-string variable whose server must answer a TCP connect for the gate to open.
5
+ *
6
+ * Only for a service a developer reaches through a local address that can go away — a
7
+ * port-forward, a container. A populated variable pointing at nothing then closes the gate with
8
+ * a printed reason instead of failing every suite behind it on a refused connection.
9
+ */
10
+ export interface Reachable<E> {
11
+ key: keyof E & string
12
+ defaultPort: number
13
+ }
package/src/types.ts ADDED
@@ -0,0 +1,49 @@
1
+ export interface IntegrationGate<E> {
2
+ skip: boolean
3
+ reason?: string
4
+ env: Partial<E>
5
+ }
6
+
7
+ export interface MongoEnv {
8
+ MONGO_URL: string
9
+ MONGO_TEST_DB_PREFIX: string
10
+ }
11
+
12
+ export interface RedisEnv {
13
+ REDIS_URL: string
14
+ REDIS_TEST_KEY_PREFIX: string
15
+ }
16
+
17
+ export interface S3Env {
18
+ S3_ENDPOINT: string
19
+ S3_KEY: string
20
+ S3_SECRET: string
21
+ S3_TEST_BUCKET: string
22
+ S3_REGION: string
23
+ }
24
+
25
+ export interface KubeEnv {
26
+ KUBE_CONFIG: string
27
+ KUBE_TEST_OK: string
28
+ }
29
+
30
+ export interface PostgresEnv {
31
+ POSTGRES_URL: string
32
+ POSTGRES_TEST_DB_PREFIX: string
33
+ }
34
+
35
+ export interface SmtpEnv {
36
+ SMTP_HOST: string
37
+ SMTP_PORT: string
38
+ SMTP_SECURE: string
39
+ SMTP_USER: string
40
+ SMTP_PASSWORD: string
41
+ SMTP_FROM: string
42
+ /** Mailbox the specs deliver to. Required — these tests send real mail. */
43
+ SMTP_TEST_TO: string
44
+ }
45
+
46
+ export interface ProbeTarget {
47
+ host: string
48
+ port: number
49
+ }