@harperfast/integration-testing 0.1.0 → 0.3.0-0

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.
Files changed (56) hide show
  1. package/README.md +71 -5
  2. package/dist/harperLifecycle.d.ts +176 -0
  3. package/dist/harperLifecycle.js +71 -40
  4. package/dist/harperLifecycle.js.map +1 -1
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/loopbackAddressPool.d.ts +50 -0
  9. package/dist/run.d.ts +2 -0
  10. package/dist/security/certGenUtils.d.ts +52 -0
  11. package/dist/security/certGenUtils.js +170 -0
  12. package/dist/security/certGenUtils.js.map +1 -0
  13. package/dist/security/crl/generate-test-certs.d.ts +34 -0
  14. package/dist/security/crl/generate-test-certs.js +81 -0
  15. package/dist/security/crl/generate-test-certs.js.map +1 -0
  16. package/dist/security/ocsp/generate-test-certs.d.ts +55 -0
  17. package/dist/security/ocsp/generate-test-certs.js +106 -0
  18. package/dist/security/ocsp/generate-test-certs.js.map +1 -0
  19. package/dist/security/ocspServer.d.ts +18 -0
  20. package/dist/security/ocspServer.js +132 -0
  21. package/dist/security/ocspServer.js.map +1 -0
  22. package/dist/securityServices.d.ts +49 -0
  23. package/dist/securityServices.js +120 -0
  24. package/dist/securityServices.js.map +1 -0
  25. package/dist/src/harperLifecycle.d.ts +156 -0
  26. package/dist/src/harperLifecycle.js +315 -0
  27. package/dist/src/harperLifecycle.js.map +1 -0
  28. package/dist/src/index.d.ts +3 -0
  29. package/dist/src/index.js +4 -0
  30. package/dist/src/index.js.map +1 -0
  31. package/dist/src/loopbackAddressPool.d.ts +50 -0
  32. package/dist/src/loopbackAddressPool.js +337 -0
  33. package/dist/src/loopbackAddressPool.js.map +1 -0
  34. package/dist/src/run.d.ts +2 -0
  35. package/dist/src/run.js +94 -0
  36. package/dist/src/run.js.map +1 -0
  37. package/dist/src/security/certGenUtils.d.ts +52 -0
  38. package/dist/src/security/certGenUtils.js +170 -0
  39. package/dist/src/security/certGenUtils.js.map +1 -0
  40. package/dist/src/security/crl/generate-test-certs.d.ts +34 -0
  41. package/dist/src/security/crl/generate-test-certs.js +81 -0
  42. package/dist/src/security/crl/generate-test-certs.js.map +1 -0
  43. package/dist/src/security/ocsp/generate-test-certs.d.ts +55 -0
  44. package/dist/src/security/ocsp/generate-test-certs.js +106 -0
  45. package/dist/src/security/ocsp/generate-test-certs.js.map +1 -0
  46. package/dist/src/security/ocspServer.d.ts +18 -0
  47. package/dist/src/security/ocspServer.js +132 -0
  48. package/dist/src/security/ocspServer.js.map +1 -0
  49. package/dist/src/securityServices.d.ts +49 -0
  50. package/dist/src/securityServices.js +120 -0
  51. package/dist/src/securityServices.js.map +1 -0
  52. package/dist/src/targz.d.ts +6 -0
  53. package/dist/src/targz.js +20 -0
  54. package/dist/src/targz.js.map +1 -0
  55. package/dist/targz.d.ts +6 -0
  56. package/package.json +5 -3
package/README.md CHANGED
@@ -97,30 +97,96 @@ Kills Harper, releases the loopback address back to the pool, and removes the in
97
97
 
98
98
  Helper to POST an operation to the Operations API and assert HTTP 200.
99
99
 
100
- ### `ContextWithHarper`
100
+ ### `createHarperContext(name?)`
101
101
 
102
- TypeScript interface for the test context populated by `startHarper()`. When using `node:test`, pass it as the suite context type:
102
+ Creates a plain object satisfying `HarperTestContext`, for use outside `node:test` (e.g. Playwright worker fixtures). The `name` is optional and used for log directory naming.
103
+
104
+ ```ts
105
+ // Playwright example
106
+ const ctx = createHarperContext(`worker-${workerInfo.workerIndex}`);
107
+ await startHarper(ctx);
108
+ ```
109
+
110
+ ### Types
111
+
112
+ There are four related TypeScript types — it helps to understand how they compose.
113
+
114
+ **`HarperContext`** is the instance data object stored at `ctx.harper` after `startHarper()` resolves. It describes a running Harper instance:
103
115
 
104
116
  ```ts
105
117
  interface HarperContext {
106
- dataRootDir: string; // Harper install directory
118
+ dataRootDir: string; // absolute path to the Harper install directory
107
119
  admin: { username: string; password: string };
108
120
  httpURL: string; // e.g. 'http://127.0.0.2:9926'
109
121
  operationsAPIURL: string; // e.g. 'http://127.0.0.2:9925'
110
122
  hostname: string; // e.g. '127.0.0.2'
111
123
  process: ChildProcess;
112
- logDir?: string;
124
+ logDir?: string; // set when HARPER_INTEGRATION_TEST_LOG_DIR is configured
125
+ startupOutput?: { stdout: string; stderr: string }; // captured startup output
126
+ }
127
+ ```
128
+
129
+ **`HarperTestContext`** is the minimal context shape accepted by `startHarper()`, `setupHarperWithFixture()`, `killHarper()`, and `teardownHarper()`. It is intentionally loose so it can be satisfied by a plain object or a `node:test` context:
130
+
131
+ ```ts
132
+ interface HarperTestContext {
133
+ name?: string; // used for log directory naming
134
+ harper?: Partial<HarperContext>; // populated by startHarper()
135
+ }
136
+ ```
137
+
138
+ **`StartedHarperTestContext`** is the same as `HarperTestContext` but with `harper` guaranteed to be a fully populated `HarperContext`. It is the return type of `startHarper()` and `setupHarperWithFixture()`, and the required parameter type of `killHarper()` and `teardownHarper()`:
139
+
140
+ ```ts
141
+ interface StartedHarperTestContext extends HarperTestContext {
142
+ harper: HarperContext;
113
143
  }
114
144
  ```
115
145
 
146
+ **`ContextWithHarper`** is for `node:test` only. It extends both `SuiteContext` and `TestContext` from `node:test` with `harper: HarperContext`, so you can use it as the typed context parameter in a `suite()` callback:
147
+
148
+ ```ts
149
+ // node:test usage
150
+ suite('my suite', (ctx: ContextWithHarper) => {
151
+ before(async () => { await startHarper(ctx); });
152
+ after(async () => { await teardownHarper(ctx); });
153
+
154
+ test('example', async () => {
155
+ const res = await fetch(ctx.harper.httpURL);
156
+ });
157
+ });
158
+ ```
159
+
160
+ If you are not using `node:test`, use `createHarperContext()` to create a plain `HarperTestContext` instead.
161
+
116
162
  ### Server Log Capture
117
163
 
118
- When `HARPER_INTEGRATION_TEST_LOG_DIR` is set, each Harper instance writes its logs to a per-suite subdirectory. Logs from passing suites are automatically cleaned up; only failing suite logs are retained.
164
+ When `HARPER_INTEGRATION_TEST_LOG_DIR` is set, each Harper instance writes its logs to a per-suite subdirectory. Logs are preserved for the lifetime of the log directory. In CI, combine with artifact upload steps that run on failure to capture logs from failing runs.
119
165
 
120
166
  ```sh
121
167
  HARPER_INTEGRATION_TEST_LOG_DIR=/tmp/harper-test-logs npx harper-integration-test-run "integrationTests/**/*.test.ts"
122
168
  ```
123
169
 
170
+ Additionally, `startupOutput` on `HarperContext` provides the captured stdout/stderr from Harper startup for programmatic access (e.g. attaching to Playwright test results).
171
+
172
+ ### `HarperStartupError`
173
+
174
+ When Harper fails to start or times out, a `HarperStartupError` is thrown. It extends `Error` and includes structured `stdout` and `stderr` properties for diagnostics:
175
+
176
+ ```ts
177
+ import { HarperStartupError } from '@harperfast/integration-testing';
178
+
179
+ try {
180
+ await startHarper(ctx);
181
+ } catch (error) {
182
+ if (error instanceof HarperStartupError) {
183
+ console.error('Startup failed:', error.message);
184
+ console.error('stdout:', error.stdout);
185
+ console.error('stderr:', error.stderr);
186
+ }
187
+ }
188
+ ```
189
+
124
190
  ### `targz(dirPath)`
125
191
 
126
192
  Packs and compresses a directory into a base64-encoded tar.gz string. Useful for `deploy_component` Operations API calls.
@@ -0,0 +1,176 @@
1
+ import { ChildProcess } from 'node:child_process';
2
+ import { type SuiteContext, type TestContext } from 'node:test';
3
+ /**
4
+ * Minimal context interface required by startHarper/teardownHarper.
5
+ *
6
+ * This is intentionally loose so it can be satisfied by:
7
+ * - node:test SuiteContext/TestContext objects (via ContextWithHarper)
8
+ * - Plain objects (e.g. Playwright worker fixtures: `createHarperContext()`)
9
+ */
10
+ export interface HarperTestContext {
11
+ /** Optional name used for log directory naming (e.g. suite name or Playwright worker index). */
12
+ name?: string;
13
+ /** Populated by startHarper(). May be pre-seeded with dataRootDir/hostname to reuse across restarts. */
14
+ harper?: Partial<HarperContext>;
15
+ }
16
+ /**
17
+ * A started context — harper is fully populated after startHarper() resolves.
18
+ */
19
+ export interface StartedHarperTestContext extends HarperTestContext {
20
+ harper: HarperContext;
21
+ }
22
+ /**
23
+ * Creates a plain object satisfying HarperTestContext, for use outside node:test
24
+ * (e.g. as a Playwright worker fixture).
25
+ *
26
+ * @param name Optional name for log directory naming (e.g. Playwright worker index).
27
+ */
28
+ export declare function createHarperContext(name?: string): HarperTestContext;
29
+ export declare const OPERATIONS_API_PORT = 9925;
30
+ export declare const DEFAULT_ADMIN_USERNAME = "admin";
31
+ export declare const DEFAULT_ADMIN_PASSWORD = "Abc1234!";
32
+ export declare const DEFAULT_STARTUP_TIMEOUT_MS: number;
33
+ /**
34
+ * The runtime to use for running Harper during tests.
35
+ * Set via the HARPER_RUNTIME environment variable ('node' or 'bun').
36
+ * Defaults to 'node'.
37
+ */
38
+ export declare const HARPER_RUNTIME: 'node' | 'bun';
39
+ /**
40
+ * Options for setting up a Harper instance.
41
+ */
42
+ export interface StartHarperOptions {
43
+ /**
44
+ * Timeout in milliseconds to wait for Harper to start.
45
+ * @default 30000
46
+ */
47
+ startupTimeoutMs?: number;
48
+ /**
49
+ * Additional configuration options to pass to the Harper CLI.
50
+ */
51
+ config?: any;
52
+ /**
53
+ * Environment variables to set when running Harper.
54
+ */
55
+ env?: any;
56
+ /**
57
+ * Explicit path to the Harper CLI script (dist/bin/harper.js).
58
+ * If not provided, resolution order is:
59
+ * 1. This option
60
+ * 2. HARPER_INTEGRATION_TEST_INSTALL_SCRIPT environment variable
61
+ * 3. Auto-resolved from 'harper' package in node_modules
62
+ */
63
+ harperBinPath?: string;
64
+ }
65
+ export interface HarperContext {
66
+ /** Absolute path to the Harper installation directory */
67
+ dataRootDir: string;
68
+ /** Admin credentials for the Harper instance */
69
+ admin: {
70
+ /** Admin username (default: 'admin') */
71
+ username: string;
72
+ /** Admin password (default: 'Abc1234!') */
73
+ password: string;
74
+ };
75
+ /** HTTP URL for the Harper instance (e.g., 'http://127.0.0.2:9926') */
76
+ httpURL: string;
77
+ /** Operations API URL (e.g., 'http://127.0.0.2:9925') */
78
+ operationsAPIURL: string;
79
+ /** Assigned loopback IP address (e.g., '127.0.0.2') */
80
+ hostname: string;
81
+ /** Child process for the Harper instance */
82
+ process: ChildProcess;
83
+ /** Absolute path to the log directory for this suite (only set when HARPER_INTEGRATION_TEST_LOG_DIR is configured) */
84
+ logDir?: string;
85
+ /** Captured stdout/stderr from Harper startup, up to the point it reported ready. */
86
+ startupOutput?: {
87
+ stdout: string;
88
+ stderr: string;
89
+ };
90
+ }
91
+ /**
92
+ * Test context interface with Harper instance details, for use with node:test.
93
+ *
94
+ * This interface is populated by `startHarper()` and contains
95
+ * all necessary information to interact with the test Harper instance.
96
+ *
97
+ * For use outside node:test (e.g. Playwright), use `createHarperContext()` to
98
+ * create a plain object satisfying `HarperTestContext` instead.
99
+ */
100
+ export interface ContextWithHarper extends SuiteContext, TestContext {
101
+ harper: HarperContext;
102
+ }
103
+ /**
104
+ * Error thrown when a Harper process fails to start or times out.
105
+ * Includes captured stdout and stderr for diagnostics.
106
+ */
107
+ export declare class HarperStartupError extends Error {
108
+ stdout: string;
109
+ stderr: string;
110
+ constructor(message: string, stdout: string, stderr: string);
111
+ }
112
+ /**
113
+ * Sets up a Harper instance with a component pre-installed from a local directory.
114
+ *
115
+ * Copies `fixturePath` into `{dataRootDir}/components/{name}` before Harper starts,
116
+ * so the component is available on the first request without a post-startup deploy.
117
+ * Use this when tests need a known route available at startup (e.g. mTLS cert tests).
118
+ *
119
+ * @param ctx - The test context to populate with Harper instance details
120
+ * @param fixturePath - Absolute path to the component directory to pre-install
121
+ * @param options - Optional configuration for the setup process
122
+ */
123
+ export declare function setupHarperWithFixture(ctx: HarperTestContext, fixturePath: string, options?: StartHarperOptions): Promise<StartedHarperTestContext>;
124
+ /**
125
+ * Sets up and starts a Harper instance for testing.
126
+ *
127
+ * @param ctx - The test context to populate with Harper instance details
128
+ * @param options - Optional configuration for the setup process
129
+ * @returns The context with the `harper` property populated
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * suite('My tests', (ctx: ContextWithHarper) => {
134
+ * before(async () => {
135
+ * await startHarper(ctx);
136
+ * });
137
+ *
138
+ * after(async () => {
139
+ * await teardownHarper(ctx);
140
+ * });
141
+ *
142
+ * test('can connect', async () => {
143
+ * const response = await fetch(ctx.harper.httpURL);
144
+ * // ...
145
+ * });
146
+ * });
147
+ * ```
148
+ */
149
+ export declare function startHarper(ctx: HarperTestContext, options?: StartHarperOptions): Promise<StartedHarperTestContext>;
150
+ /**
151
+ * Kill harper process (can be used for teardown, or killing it before a restart)
152
+ * @param ctx
153
+ */
154
+ export declare function killHarper(ctx: StartedHarperTestContext): Promise<void>;
155
+ /**
156
+ * Tears down a Harper instance and cleans up all resources.
157
+ *
158
+ * This function stops the Harper instance, releases the loopback address,
159
+ * and removes the installation directory.
160
+ * @param ctx - The test context with Harper instance details
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * suite('My tests', (ctx: ContextWithHarper) => {
165
+ * before(async () => {
166
+ * await startHarper(ctx);
167
+ * });
168
+ *
169
+ * after(async () => {
170
+ * await teardownHarper(ctx);
171
+ * });
172
+ * });
173
+ * ```
174
+ */
175
+ export declare function teardownHarper(ctx: StartedHarperTestContext): Promise<void>;
176
+ export declare function sendOperation(context: HarperContext, operation: any): Promise<any>;
@@ -1,5 +1,5 @@
1
1
  import { spawn, ChildProcess } from 'node:child_process';
2
- import { createWriteStream, existsSync, rmSync } from 'node:fs';
2
+ import { createWriteStream, existsSync } from 'node:fs';
3
3
  import { join, basename } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { mkdtemp, mkdir, rm, cp } from 'node:fs/promises';
@@ -19,13 +19,19 @@ export function createHarperContext(name) {
19
19
  // Constants
20
20
  const HTTP_PORT = 9926;
21
21
  const HTTPS_PORT = 9927;
22
+ const MQTT_PORT = 1883;
23
+ const MQTTS_PORT = 8883;
22
24
  export const OPERATIONS_API_PORT = 9925;
23
25
  export const DEFAULT_ADMIN_USERNAME = 'admin';
24
26
  export const DEFAULT_ADMIN_PASSWORD = 'Abc1234!';
25
- export const DEFAULT_STARTUP_TIMEOUT_MS = process.env.HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS
26
- ? parseInt(process.env.HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS, 10)
27
- : 30000;
27
+ export const DEFAULT_STARTUP_TIMEOUT_MS = parseInt(process.env.HARPER_INTEGRATION_TEST_STARTUP_TIMEOUT_MS || '', 10) || 60000;
28
28
  const LOG_DIR = process.env.HARPER_INTEGRATION_TEST_LOG_DIR;
29
+ /**
30
+ * The runtime to use for running Harper during tests.
31
+ * Set via the HARPER_RUNTIME environment variable ('node' or 'bun').
32
+ * Defaults to 'node'.
33
+ */
34
+ export const HARPER_RUNTIME = process.env.HARPER_RUNTIME || 'node';
29
35
  /**
30
36
  * Gets the path to the Harper CLI script.
31
37
  *
@@ -65,6 +71,14 @@ function getHarperScript(harperBinPath) {
65
71
  ` - HARPER_INTEGRATION_TEST_INSTALL_SCRIPT environment variable\n` +
66
72
  ` - Install 'harper' as a dependency in your project`);
67
73
  }
74
+ /**
75
+ * Strips ANSI escape sequences (colors, bold, underline, cursor movement, etc.) from a string.
76
+ */
77
+ // eslint-disable-next-line no-control-regex
78
+ const ANSI_REGEX = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nq-uy=><~]/g;
79
+ function stripAnsi(str) {
80
+ return str.replace(ANSI_REGEX, '');
81
+ }
68
82
  /**
69
83
  * Sanitizes a string for use as a filesystem directory name.
70
84
  */
@@ -74,17 +88,42 @@ function sanitizeForFilesystem(name) {
74
88
  .replace(/_+/g, '_')
75
89
  .substring(0, 100);
76
90
  }
91
+ /**
92
+ * Error thrown when a Harper process fails to start or times out.
93
+ * Includes captured stdout and stderr for diagnostics.
94
+ */
95
+ export class HarperStartupError extends Error {
96
+ stdout;
97
+ stderr;
98
+ constructor(message, stdout, stderr) {
99
+ let fullMessage = message;
100
+ if (stdout) {
101
+ fullMessage += `\n\nstdout:\n${stdout}`;
102
+ }
103
+ if (stderr) {
104
+ fullMessage += `\n\nstderr:\n${stderr}`;
105
+ }
106
+ super(fullMessage);
107
+ this.name = 'HarperStartupError';
108
+ this.stdout = stdout;
109
+ this.stderr = stderr;
110
+ }
111
+ }
77
112
  /**
78
113
  * Runs a Harper CLI command and captures output.
79
114
  *
80
115
  * When `logDir` is provided, stdout and stderr are also written to files
81
116
  * (`stdout.log` and `stderr.log`) in that directory.
82
117
  *
83
- * @throws {AssertionError} If the command exits with a non-zero status code
118
+ * @throws {HarperStartupError} If the command times out or exits with a non-zero status code
84
119
  */
85
- function runHarperCommand({ args, env, completionMessage, logDir, harperBinPath, }) {
120
+ function runHarperCommand({ args, env, completionMessage, logDir, harperBinPath, timeoutMs, }) {
86
121
  const harperScript = getHarperScript(harperBinPath);
87
- const proc = spawn('node', ['--trace-warnings', '--force-node-api-uncaught-exceptions-policy=true', harperScript, ...args], {
122
+ const runtime = HARPER_RUNTIME;
123
+ const runtimeArgs = runtime === 'bun'
124
+ ? [harperScript, ...args]
125
+ : ['--trace-warnings', '--force-node-api-uncaught-exceptions-policy=true', harperScript, ...args];
126
+ const proc = spawn(runtime, runtimeArgs, {
88
127
  env: { ...process.env, ...env },
89
128
  });
90
129
  let stdoutStream;
@@ -93,32 +132,27 @@ function runHarperCommand({ args, env, completionMessage, logDir, harperBinPath,
93
132
  stdoutStream = createWriteStream(join(logDir, 'stdout.log'));
94
133
  stderrStream = createWriteStream(join(logDir, 'stderr.log'));
95
134
  }
135
+ const effectiveTimeout = timeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS;
96
136
  return new Promise((resolve, reject) => {
97
137
  let stdout = '';
98
138
  let stderr = '';
99
139
  let timer = setTimeout(() => {
100
- let errorMessage = `Harper process timed out after ${DEFAULT_STARTUP_TIMEOUT_MS}ms`;
101
- if (stdout) {
102
- errorMessage += `\n\nstdout:\n${stdout}`;
103
- }
104
- if (stderr) {
105
- errorMessage += `\n\nstderr:\n${stderr}`;
106
- }
107
- reject(errorMessage);
140
+ reject(new HarperStartupError(`Harper process timed out after ${effectiveTimeout}ms`, stdout, stderr));
108
141
  proc.kill();
109
- }, DEFAULT_STARTUP_TIMEOUT_MS);
142
+ }, effectiveTimeout);
110
143
  proc.stdout?.on('data', (data) => {
111
- const dataString = data.toString();
112
- stdoutStream?.write(data);
144
+ const dataString = stripAnsi(data.toString());
145
+ stdoutStream?.write(dataString);
113
146
  if (completionMessage && dataString.includes(completionMessage)) {
114
147
  clearTimeout(timer);
115
- resolve(proc);
148
+ resolve({ process: proc, stdout, stderr });
116
149
  }
117
150
  stdout += dataString;
118
151
  });
119
152
  proc.stderr?.on('data', (data) => {
120
- stderrStream?.write(data);
121
- stderr += data.toString();
153
+ const dataString = stripAnsi(data.toString());
154
+ stderrStream?.write(dataString);
155
+ stderr += dataString;
122
156
  });
123
157
  proc.on('error', (error) => {
124
158
  reject(error);
@@ -126,15 +160,12 @@ function runHarperCommand({ args, env, completionMessage, logDir, harperBinPath,
126
160
  proc.on('exit', (statusCode, signal) => {
127
161
  clearTimeout(timer);
128
162
  if (statusCode === 0) {
129
- resolve(proc);
163
+ resolve({ process: proc, stdout, stderr });
130
164
  }
131
165
  else {
132
- let errorMessage = `Harper process failed with exit code/signal ${statusCode ?? signal}`;
166
+ const errorMessage = `Harper process failed with exit code/signal ${statusCode ?? signal}`;
133
167
  stderrStream?.write(errorMessage);
134
- if (stderr) {
135
- errorMessage += `\n\nstderr:\n${stderr}`;
136
- }
137
- reject(errorMessage);
168
+ reject(new HarperStartupError(errorMessage, stdout, stderr));
138
169
  }
139
170
  stdoutStream?.end();
140
171
  stderrStream?.end();
@@ -192,26 +223,18 @@ export async function startHarper(ctx, options) {
192
223
  let logDir;
193
224
  if (LOG_DIR) {
194
225
  const suiteName = sanitizeForFilesystem(ctx.name || 'unknown');
195
- logDir = join(LOG_DIR, `${suiteName}-${sanitizeForFilesystem(loopbackAddress)}`);
226
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
227
+ logDir = join(LOG_DIR, `${suiteName}-${sanitizeForFilesystem(loopbackAddress)}-${timestamp}`);
196
228
  await mkdir(logDir, { recursive: true });
197
229
  }
198
230
  // Point Harper's log directory to the suite log dir so hdb.log is preserved for upload
199
231
  const config = { ...options?.config };
200
232
  if (logDir) {
201
233
  config.logging = { ...config.logging, root: logDir };
202
- // Clean up log directory on successful exit — only keep logs when tests fail
203
- process.on('exit', (code) => {
204
- if (code === 0) {
205
- try {
206
- rmSync(logDir, { recursive: true, force: true });
207
- }
208
- catch { }
209
- }
210
- });
211
234
  }
212
235
  const args = [
213
236
  `--ROOTPATH=${dataRootDir}`,
214
- '--DEFAULTS_MODE=dev',
237
+ `--AUTHENTICATION_AUTHORIZELOCAL=true`,
215
238
  `--HDB_ADMIN_USERNAME=${DEFAULT_ADMIN_USERNAME}`,
216
239
  `--HDB_ADMIN_PASSWORD=${DEFAULT_ADMIN_PASSWORD}`,
217
240
  '--THREADS_COUNT=1',
@@ -219,6 +242,8 @@ export async function startHarper(ctx, options) {
219
242
  `--NODE_HOSTNAME=${loopbackAddress}`,
220
243
  `--HTTP_PORT=${loopbackAddress}:${HTTP_PORT}`,
221
244
  `--OPERATIONSAPI_NETWORK_PORT=${loopbackAddress}:${OPERATIONS_API_PORT}`,
245
+ `--MQTT_NETWORK_PORT=${loopbackAddress}:${MQTT_PORT}`,
246
+ `--MQTT_NETWORK_SECUREPORT=${loopbackAddress}:${MQTTS_PORT}`,
222
247
  '--LOGGING_LEVEL=debug',
223
248
  '--LOGGING_STDSTREAMS=false',
224
249
  ];
@@ -232,12 +257,13 @@ export async function startHarper(ctx, options) {
232
257
  HARPER_SET_CONFIG: JSON.stringify(config),
233
258
  ...options?.env,
234
259
  };
235
- const harperProcess = await runHarperCommand({
260
+ const result = await runHarperCommand({
236
261
  args,
237
262
  env: harperEnv,
238
263
  completionMessage: 'successfully started',
239
264
  logDir,
240
265
  harperBinPath: options?.harperBinPath,
266
+ timeoutMs: options?.startupTimeoutMs,
241
267
  });
242
268
  ctx.harper = {
243
269
  dataRootDir,
@@ -248,8 +274,9 @@ export async function startHarper(ctx, options) {
248
274
  httpURL: `http://${loopbackAddress}:${HTTP_PORT}`,
249
275
  operationsAPIURL: `http://${loopbackAddress}:${OPERATIONS_API_PORT}`,
250
276
  hostname: loopbackAddress,
251
- process: harperProcess,
277
+ process: result.process,
252
278
  logDir,
279
+ startupOutput: { stdout: result.stdout, stderr: result.stderr },
253
280
  };
254
281
  return ctx;
255
282
  }
@@ -258,6 +285,8 @@ export async function startHarper(ctx, options) {
258
285
  * @param ctx
259
286
  */
260
287
  export async function killHarper(ctx) {
288
+ if (!ctx.harper?.process)
289
+ return;
261
290
  await new Promise((resolve) => {
262
291
  let timer;
263
292
  ctx.harper.process.on('exit', () => {
@@ -297,6 +326,8 @@ export async function killHarper(ctx) {
297
326
  * ```
298
327
  */
299
328
  export async function teardownHarper(ctx) {
329
+ if (!ctx.harper)
330
+ return;
300
331
  await killHarper(ctx);
301
332
  await releaseLoopbackAddress(ctx.harper.hostname);
302
333
  // a few retries are typically necessary, might take a sec for a process to finish, especially since rocksdb may be flushing
@@ -1 +1 @@
1
- {"version":3,"file":"harperLifecycle.js","sourceRoot":"","sources":["../src/harperLifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harperLifecycle.js","sourceRoot":"","sources":["../src/harperLifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { startHarper, setupHarperWithFixture, killHarper, teardownHarper, sendOperation, createHarperContext, HarperStartupError, OPERATIONS_API_PORT, DEFAULT_ADMIN_USERNAME, DEFAULT_ADMIN_PASSWORD, DEFAULT_STARTUP_TIMEOUT_MS, HARPER_RUNTIME, type StartHarperOptions, type HarperContext, type HarperTestContext, type StartedHarperTestContext, type ContextWithHarper, } from './harperLifecycle.ts';
2
+ export { validateLoopbackAddressPool, getNextAvailableLoopbackAddress, releaseLoopbackAddress, releaseAllLoopbackAddressesForCurrentProcess, } from './loopbackAddressPool.ts';
3
+ export { targz } from './targz.ts';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { startHarper, setupHarperWithFixture, killHarper, teardownHarper, sendOperation, createHarperContext, OPERATIONS_API_PORT, DEFAULT_ADMIN_USERNAME, DEFAULT_ADMIN_PASSWORD, DEFAULT_STARTUP_TIMEOUT_MS, } from "./harperLifecycle.js";
1
+ export { startHarper, setupHarperWithFixture, killHarper, teardownHarper, sendOperation, createHarperContext, HarperStartupError, OPERATIONS_API_PORT, DEFAULT_ADMIN_USERNAME, DEFAULT_ADMIN_PASSWORD, DEFAULT_STARTUP_TIMEOUT_MS, HARPER_RUNTIME, } from "./harperLifecycle.js";
2
2
  export { validateLoopbackAddressPool, getNextAvailableLoopbackAddress, releaseLoopbackAddress, releaseAllLoopbackAddressesForCurrentProcess, } from "./loopbackAddressPool.js";
3
3
  export { targz } from "./targz.js";
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,sBAAsB,EACtB,UAAU,EACV,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,GAM1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACN,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,4CAA4C,GAC5C,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,sBAAsB,EACtB,UAAU,EACV,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,cAAc,GAMd,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACN,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,4CAA4C,GAC5C,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * This method attempts to validate all loopback addresses in the pool by trying to
3
+ * bind to each one. It returns an object containing arrays of successfully bound
4
+ * loopback addresses and those that failed along with their errors.
5
+ *
6
+ * It will check all loopback addresses from 127.0.0.1 to 127.0.0.32 (by default).
7
+ *
8
+ * Use the HARPER_INTEGRATION_TEST_LOOPBACK_POOL_COUNT environment variable to
9
+ * adjust the number of loopback addresses to validate (up to 255).
10
+ */
11
+ export declare function validateLoopbackAddressPool(): Promise<{
12
+ successful: string[];
13
+ failed: {
14
+ loopbackAddress: string;
15
+ error: Error;
16
+ }[];
17
+ }>;
18
+ /**
19
+ * Retrieves the next available loopback address from the pool using a file-based
20
+ * locking mechanism to safely allocate addresses across concurrent test processes.
21
+ *
22
+ * **How it works:**
23
+ * 1. Acquires a file-based lock to prevent race conditions with other processes
24
+ * 2. Reads the pool state (a JSON array of process IDs, with null for available slots)
25
+ * 3. Finds the first available (null) slot and assigns the current process PID to it
26
+ * 4. Writes the updated pool back to disk and releases the lock
27
+ * 5. Validates that the allocated address can actually be bound to
28
+ * 6. Returns the loopback address (e.g., "127.0.0.2")
29
+ *
30
+ * If no addresses are available, waits and retries until one becomes available.
31
+ *
32
+ * **Pool file location:** `${tmpdir()}/harper-integration-test-loopback-pool.json`
33
+ * **Lock file location:** `${tmpdir()}/harper-integration-test-loopback-pool.lock`
34
+ *
35
+ * @returns A promise that resolves with an allocated loopback address
36
+ * @throws {LoopbackAddressValidationError} If the allocated address cannot be bound to
37
+ */
38
+ export declare function getNextAvailableLoopbackAddress(): Promise<string>;
39
+ /**
40
+ * Releases a loopback address back to the pool, making it available for other processes.
41
+ *
42
+ * @param address The loopback address to release (e.g., "127.0.0.1")
43
+ * @throws InvalidLoopbackAddressError if the address format is invalid
44
+ */
45
+ export declare function releaseLoopbackAddress(address: string): Promise<void>;
46
+ /**
47
+ * Releases all loopback addresses assigned to the current process.
48
+ * Useful for cleanup during graceful shutdown.
49
+ */
50
+ export declare function releaseAllLoopbackAddressesForCurrentProcess(): Promise<void>;
package/dist/run.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};