@milaboratories/pl-client 2.16.3 → 2.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/test/tcp-proxy.cjs +4 -3
- package/dist/test/tcp-proxy.cjs.map +1 -1
- package/dist/test/tcp-proxy.d.ts +1 -1
- package/dist/test/tcp-proxy.d.ts.map +1 -1
- package/dist/test/tcp-proxy.js +4 -3
- package/dist/test/tcp-proxy.js.map +1 -1
- package/dist/test/test_config.cjs +0 -2
- package/dist/test/test_config.cjs.map +1 -1
- package/dist/test/test_config.js +0 -2
- package/dist/test/test_config.js.map +1 -1
- package/package.json +3 -3
- package/src/core/connectivity.test.ts +2 -2
- package/src/test/tcp-proxy.ts +3 -3
- package/src/test/test_config.ts +0 -2
package/dist/test/tcp-proxy.cjs
CHANGED
|
@@ -37,7 +37,7 @@ async function startTcpProxy(options) {
|
|
|
37
37
|
return state.latency;
|
|
38
38
|
};
|
|
39
39
|
const connections = new Set();
|
|
40
|
-
async function disconnectAll() {
|
|
40
|
+
async function disconnectAll(delayMs = undefined) {
|
|
41
41
|
const kill = () => {
|
|
42
42
|
for (const { socket, client } of connections) {
|
|
43
43
|
if (!socket.destroyed)
|
|
@@ -47,7 +47,8 @@ async function startTcpProxy(options) {
|
|
|
47
47
|
}
|
|
48
48
|
connections.clear();
|
|
49
49
|
};
|
|
50
|
-
|
|
50
|
+
if (delayMs !== undefined)
|
|
51
|
+
await tp__namespace.setTimeout(delayMs);
|
|
51
52
|
kill();
|
|
52
53
|
}
|
|
53
54
|
const server = net__namespace
|
|
@@ -94,7 +95,7 @@ async function startTcpProxy(options) {
|
|
|
94
95
|
});
|
|
95
96
|
});
|
|
96
97
|
server.listen({ port: port ?? 0 }, () => {
|
|
97
|
-
console.log('
|
|
98
|
+
console.log('Test TCP proxy server started on', server.address());
|
|
98
99
|
});
|
|
99
100
|
// Wait for proxy to be ready
|
|
100
101
|
await new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcp-proxy.cjs","sources":["../../src/test/tcp-proxy.ts"],"sourcesContent":["import * as net from 'node:net';\nimport type { AddressInfo } from 'node:net';\nimport { Transform } from 'node:stream';\nimport type { TransformCallback } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport * as timers from 'node:timers/promises';\n\nexport type TcpProxyOptions = {\n port?: number;\n targetPort: number;\n latency: number;\n verbose?: boolean;\n};\n\nexport async function startTcpProxy(options: TcpProxyOptions) {\n const { port, targetPort } = options;\n\n const state = {\n latency: options.latency,\n };\n\n const setLatency = (latency: number) => {\n state.latency = latency;\n };\n\n const getLatency = () => {\n return state.latency;\n };\n\n const connections = new Set<{ socket: net.Socket; client: net.Socket }>();\n\n async function disconnectAll() {\n const kill = () => {\n for (const { socket, client } of connections) {\n if (!socket.destroyed) socket.destroy();\n if (!client.destroyed) client.destroy();\n }\n connections.clear();\n };\n await timers.setTimeout(
|
|
1
|
+
{"version":3,"file":"tcp-proxy.cjs","sources":["../../src/test/tcp-proxy.ts"],"sourcesContent":["import * as net from 'node:net';\nimport type { AddressInfo } from 'node:net';\nimport { Transform } from 'node:stream';\nimport type { TransformCallback } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport * as timers from 'node:timers/promises';\n\nexport type TcpProxyOptions = {\n port?: number;\n targetPort: number;\n latency: number;\n verbose?: boolean;\n};\n\nexport async function startTcpProxy(options: TcpProxyOptions) {\n const { port, targetPort } = options;\n\n const state = {\n latency: options.latency,\n };\n\n const setLatency = (latency: number) => {\n state.latency = latency;\n };\n\n const getLatency = () => {\n return state.latency;\n };\n\n const connections = new Set<{ socket: net.Socket; client: net.Socket }>();\n\n async function disconnectAll(delayMs: number | undefined = undefined) {\n const kill = () => {\n for (const { socket, client } of connections) {\n if (!socket.destroyed) socket.destroy();\n if (!client.destroyed) client.destroy();\n }\n connections.clear();\n };\n if (delayMs !== undefined) await timers.setTimeout(delayMs);\n kill();\n };\n\n const server = net\n .createServer((socket: net.Socket) => {\n const client = net.createConnection({ port: targetPort }, () => {\n if (options.verbose) console.log(`connected to ${targetPort}`);\n });\n\n const pair = { socket, client };\n connections.add(pair);\n const onClose = () => connections.delete(pair);\n socket.on('close', onClose);\n client.on('close', onClose);\n\n class LatencyTransform extends Transform {\n private pendingTimer?: NodeJS.Timeout;\n constructor() {\n super();\n }\n\n _transform(chunk: Buffer, _enc: BufferEncoding, callback: TransformCallback) {\n // Backpressure is respected by delaying the callback until after push\n this.pendingTimer = setTimeout(() => {\n this.pendingTimer = undefined;\n this.push(chunk);\n callback();\n }, state.latency);\n }\n\n _destroy(err: Error | null, cb: (error?: Error | null) => void) {\n if (this.pendingTimer) clearTimeout(this.pendingTimer);\n this.pendingTimer = undefined;\n cb(err);\n }\n }\n\n const toClientLatency = new LatencyTransform();\n const toTargetLatency = new LatencyTransform();\n\n // Bidirectional pipelines with latency and error propagation\n pipeline(socket, toTargetLatency, client).catch((err) => {\n socket.destroy(err);\n client.destroy(err);\n });\n\n pipeline(client, toClientLatency, socket).catch((err) => {\n socket.destroy(err);\n client.destroy(err);\n });\n });\n\n server.listen({ port: port ?? 0 }, () => {\n console.log('Test TCP proxy server started on', server.address());\n });\n\n // Wait for proxy to be ready\n await new Promise<void>((resolve, reject) => {\n if (server.listening) return resolve();\n const onError = (err: Error) => {\n server.off('listening', onListening);\n reject(err);\n };\n const onListening = () => {\n server.off('error', onError);\n resolve();\n };\n server.once('error', onError);\n server.once('listening', onListening);\n });\n\n return {\n server,\n get port() { return (server.address() as AddressInfo)?.port; },\n setLatency,\n getLatency,\n disconnectAll,\n close: async () => {\n await new Promise<void>((resolve) => {\n server.close(() => resolve());\n });\n },\n };\n}\n\nexport type TestTcpProxy = Awaited<ReturnType<typeof startTcpProxy>>;\n"],"names":["timers","net","Transform","pipeline"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcO,eAAe,aAAa,CAAC,OAAwB,EAAA;AAC1D,IAAA,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO;AAEpC,IAAA,MAAM,KAAK,GAAG;QACZ,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB;AAED,IAAA,MAAM,UAAU,GAAG,CAAC,OAAe,KAAI;AACrC,QAAA,KAAK,CAAC,OAAO,GAAG,OAAO;AACzB,IAAA,CAAC;IAED,MAAM,UAAU,GAAG,MAAK;QACtB,OAAO,KAAK,CAAC,OAAO;AACtB,IAAA,CAAC;AAED,IAAA,MAAM,WAAW,GAAG,IAAI,GAAG,EAA8C;AAEzE,IAAA,eAAe,aAAa,CAAC,OAAA,GAA8B,SAAS,EAAA;QAClE,MAAM,IAAI,GAAG,MAAK;YAChB,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,WAAW,EAAE;gBAC5C,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,MAAM,CAAC,OAAO,EAAE;gBACvC,IAAI,CAAC,MAAM,CAAC,SAAS;oBAAE,MAAM,CAAC,OAAO,EAAE;YACzC;YACA,WAAW,CAAC,KAAK,EAAE;AACrB,QAAA,CAAC;QACD,IAAI,OAAO,KAAK,SAAS;AAAE,YAAA,MAAMA,aAAM,CAAC,UAAU,CAAC,OAAO,CAAC;AAC3D,QAAA,IAAI,EAAE;IACR;IAEA,MAAM,MAAM,GAAGC;AACZ,SAAA,YAAY,CAAC,CAAC,MAAkB,KAAI;AACnC,QAAA,MAAM,MAAM,GAAGA,cAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,MAAK;YAC7D,IAAI,OAAO,CAAC,OAAO;AAAE,gBAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,CAAA,CAAE,CAAC;AAChE,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE;AAC/B,QAAA,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QACrB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;AAC9C,QAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;AAC3B,QAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;QAE3B,MAAM,gBAAiB,SAAQC,qBAAS,CAAA;AAC9B,YAAA,YAAY;AACpB,YAAA,WAAA,GAAA;AACE,gBAAA,KAAK,EAAE;YACT;AAEA,YAAA,UAAU,CAAC,KAAa,EAAE,IAAoB,EAAE,QAA2B,EAAA;;AAEzE,gBAAA,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,MAAK;AAClC,oBAAA,IAAI,CAAC,YAAY,GAAG,SAAS;AAC7B,oBAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AAChB,oBAAA,QAAQ,EAAE;AACZ,gBAAA,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;YACnB;YAEA,QAAQ,CAAC,GAAiB,EAAE,EAAkC,EAAA;gBAC5D,IAAI,IAAI,CAAC,YAAY;AAAE,oBAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;AACtD,gBAAA,IAAI,CAAC,YAAY,GAAG,SAAS;gBAC7B,EAAE,CAAC,GAAG,CAAC;YACT;AACD;AAED,QAAA,MAAM,eAAe,GAAG,IAAI,gBAAgB,EAAE;AAC9C,QAAA,MAAM,eAAe,GAAG,IAAI,gBAAgB,EAAE;;AAG9C,QAAAC,iBAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAI;AACtD,YAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;AACnB,YAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;AACrB,QAAA,CAAC,CAAC;AAEF,QAAAA,iBAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAI;AACtD,YAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;AACnB,YAAA,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;AACrB,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,CAAC;AAEJ,IAAA,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,MAAK;QACtC,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AACnE,IAAA,CAAC,CAAC;;IAGF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;QAC1C,IAAI,MAAM,CAAC,SAAS;YAAE,OAAO,OAAO,EAAE;AACtC,QAAA,MAAM,OAAO,GAAG,CAAC,GAAU,KAAI;AAC7B,YAAA,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC;AACb,QAAA,CAAC;QACD,MAAM,WAAW,GAAG,MAAK;AACvB,YAAA,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC;AAC5B,YAAA,OAAO,EAAE;AACX,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;AAC7B,QAAA,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC;AACvC,IAAA,CAAC,CAAC;IAEF,OAAO;QACL,MAAM;QACN,IAAI,IAAI,GAAA,EAAK,OAAQ,MAAM,CAAC,OAAO,EAAkB,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9D,UAAU;QACV,UAAU;QACV,aAAa;QACb,KAAK,EAAE,YAAW;AAChB,YAAA,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,KAAI;gBAClC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,EAAE,CAAC;AAC/B,YAAA,CAAC,CAAC;QACJ,CAAC;KACF;AACH;;;;"}
|
package/dist/test/tcp-proxy.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare function startTcpProxy(options: TcpProxyOptions): Promise<{
|
|
|
10
10
|
readonly port: number;
|
|
11
11
|
setLatency: (latency: number) => void;
|
|
12
12
|
getLatency: () => number;
|
|
13
|
-
disconnectAll: () => Promise<void>;
|
|
13
|
+
disconnectAll: (delayMs?: number | undefined) => Promise<void>;
|
|
14
14
|
close: () => Promise<void>;
|
|
15
15
|
}>;
|
|
16
16
|
export type TestTcpProxy = Awaited<ReturnType<typeof startTcpProxy>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcp-proxy.d.ts","sourceRoot":"","sources":["../../src/test/tcp-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAOhC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe;;;0BAO7B,MAAM
|
|
1
|
+
{"version":3,"file":"tcp-proxy.d.ts","sourceRoot":"","sources":["../../src/test/tcp-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAOhC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe;;;0BAO7B,MAAM;;8BAUG,MAAM,GAAG,SAAS;;GA4FzD;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC"}
|
package/dist/test/tcp-proxy.js
CHANGED
|
@@ -15,7 +15,7 @@ async function startTcpProxy(options) {
|
|
|
15
15
|
return state.latency;
|
|
16
16
|
};
|
|
17
17
|
const connections = new Set();
|
|
18
|
-
async function disconnectAll() {
|
|
18
|
+
async function disconnectAll(delayMs = undefined) {
|
|
19
19
|
const kill = () => {
|
|
20
20
|
for (const { socket, client } of connections) {
|
|
21
21
|
if (!socket.destroyed)
|
|
@@ -25,7 +25,8 @@ async function startTcpProxy(options) {
|
|
|
25
25
|
}
|
|
26
26
|
connections.clear();
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
if (delayMs !== undefined)
|
|
29
|
+
await tp.setTimeout(delayMs);
|
|
29
30
|
kill();
|
|
30
31
|
}
|
|
31
32
|
const server = net
|
|
@@ -72,7 +73,7 @@ async function startTcpProxy(options) {
|
|
|
72
73
|
});
|
|
73
74
|
});
|
|
74
75
|
server.listen({ port: port ?? 0 }, () => {
|
|
75
|
-
console.log('
|
|
76
|
+
console.log('Test TCP proxy server started on', server.address());
|
|
76
77
|
});
|
|
77
78
|
// Wait for proxy to be ready
|
|
78
79
|
await new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tcp-proxy.js","sources":["../../src/test/tcp-proxy.ts"],"sourcesContent":["import * as net from 'node:net';\nimport type { AddressInfo } from 'node:net';\nimport { Transform } from 'node:stream';\nimport type { TransformCallback } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport * as timers from 'node:timers/promises';\n\nexport type TcpProxyOptions = {\n port?: number;\n targetPort: number;\n latency: number;\n verbose?: boolean;\n};\n\nexport async function startTcpProxy(options: TcpProxyOptions) {\n const { port, targetPort } = options;\n\n const state = {\n latency: options.latency,\n };\n\n const setLatency = (latency: number) => {\n state.latency = latency;\n };\n\n const getLatency = () => {\n return state.latency;\n };\n\n const connections = new Set<{ socket: net.Socket; client: net.Socket }>();\n\n async function disconnectAll() {\n const kill = () => {\n for (const { socket, client } of connections) {\n if (!socket.destroyed) socket.destroy();\n if (!client.destroyed) client.destroy();\n }\n connections.clear();\n };\n await timers.setTimeout(
|
|
1
|
+
{"version":3,"file":"tcp-proxy.js","sources":["../../src/test/tcp-proxy.ts"],"sourcesContent":["import * as net from 'node:net';\nimport type { AddressInfo } from 'node:net';\nimport { Transform } from 'node:stream';\nimport type { TransformCallback } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport * as timers from 'node:timers/promises';\n\nexport type TcpProxyOptions = {\n port?: number;\n targetPort: number;\n latency: number;\n verbose?: boolean;\n};\n\nexport async function startTcpProxy(options: TcpProxyOptions) {\n const { port, targetPort } = options;\n\n const state = {\n latency: options.latency,\n };\n\n const setLatency = (latency: number) => {\n state.latency = latency;\n };\n\n const getLatency = () => {\n return state.latency;\n };\n\n const connections = new Set<{ socket: net.Socket; client: net.Socket }>();\n\n async function disconnectAll(delayMs: number | undefined = undefined) {\n const kill = () => {\n for (const { socket, client } of connections) {\n if (!socket.destroyed) socket.destroy();\n if (!client.destroyed) client.destroy();\n }\n connections.clear();\n };\n if (delayMs !== undefined) await timers.setTimeout(delayMs);\n kill();\n };\n\n const server = net\n .createServer((socket: net.Socket) => {\n const client = net.createConnection({ port: targetPort }, () => {\n if (options.verbose) console.log(`connected to ${targetPort}`);\n });\n\n const pair = { socket, client };\n connections.add(pair);\n const onClose = () => connections.delete(pair);\n socket.on('close', onClose);\n client.on('close', onClose);\n\n class LatencyTransform extends Transform {\n private pendingTimer?: NodeJS.Timeout;\n constructor() {\n super();\n }\n\n _transform(chunk: Buffer, _enc: BufferEncoding, callback: TransformCallback) {\n // Backpressure is respected by delaying the callback until after push\n this.pendingTimer = setTimeout(() => {\n this.pendingTimer = undefined;\n this.push(chunk);\n callback();\n }, state.latency);\n }\n\n _destroy(err: Error | null, cb: (error?: Error | null) => void) {\n if (this.pendingTimer) clearTimeout(this.pendingTimer);\n this.pendingTimer = undefined;\n cb(err);\n }\n }\n\n const toClientLatency = new LatencyTransform();\n const toTargetLatency = new LatencyTransform();\n\n // Bidirectional pipelines with latency and error propagation\n pipeline(socket, toTargetLatency, client).catch((err) => {\n socket.destroy(err);\n client.destroy(err);\n });\n\n pipeline(client, toClientLatency, socket).catch((err) => {\n socket.destroy(err);\n client.destroy(err);\n });\n });\n\n server.listen({ port: port ?? 0 }, () => {\n console.log('Test TCP proxy server started on', server.address());\n });\n\n // Wait for proxy to be ready\n await new Promise<void>((resolve, reject) => {\n if (server.listening) return resolve();\n const onError = (err: Error) => {\n server.off('listening', onListening);\n reject(err);\n };\n const onListening = () => {\n server.off('error', onError);\n resolve();\n };\n server.once('error', onError);\n server.once('listening', onListening);\n });\n\n return {\n server,\n get port() { return (server.address() as AddressInfo)?.port; },\n setLatency,\n getLatency,\n disconnectAll,\n close: async () => {\n await new Promise<void>((resolve) => {\n server.close(() => resolve());\n });\n },\n };\n}\n\nexport type TestTcpProxy = Awaited<ReturnType<typeof startTcpProxy>>;\n"],"names":["timers"],"mappings":"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"}
|
|
@@ -155,7 +155,6 @@ async function withTempRoot(body, options = {}) {
|
|
|
155
155
|
}
|
|
156
156
|
const client = await getTestClient(alternativeRoot, confOverrides);
|
|
157
157
|
altRootId = client.clientRoot;
|
|
158
|
-
console.log('altRootId', altRootId, altRootId.toString(16));
|
|
159
158
|
const value = await body(client, proxy);
|
|
160
159
|
const rawClient = await getTestClient();
|
|
161
160
|
try {
|
|
@@ -168,7 +167,6 @@ async function withTempRoot(body, options = {}) {
|
|
|
168
167
|
return value;
|
|
169
168
|
}
|
|
170
169
|
catch (err) {
|
|
171
|
-
console.log('ERROR stack trace:', err.stack);
|
|
172
170
|
console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${types.resourceIdToString(altRootId)})`);
|
|
173
171
|
throw err;
|
|
174
172
|
// throw new Error('withTempRoot error: ' + err.message, { cause: err });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test_config.cjs","sources":["../../src/test/test_config.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport { LLPlClient } from '../core/ll_client';\nimport type { AuthInformation, AuthOps, PlClientConfig } from '../core/config';\nimport { plAddressToConfig } from '../core/config';\nimport { UnauthenticatedPlClient } from '../core/unauth_client';\nimport { PlClient } from '../core/client';\nimport { randomUUID } from 'node:crypto';\nimport type { OptionalResourceId } from '../core/types';\nimport { NullResourceId, resourceIdToString } from '../core/types';\nimport { inferAuthRefreshTime } from '../core/auth';\nimport * as path from 'node:path';\nimport type { TestTcpProxy } from './tcp-proxy';\nimport { startTcpProxy } from './tcp-proxy';\n\nexport {\n TestTcpProxy,\n};\n\nexport interface TestConfig {\n address: string;\n test_proxy?: string;\n test_user?: string;\n test_password?: string;\n}\n\nconst CONFIG_FILE = 'test_config.json';\n// const AUTH_DATA_FILE = '.test_auth.json';\n\nlet authDataFilePath: string | undefined;\n\nfunction getFullAuthDataFilePath() {\n if (authDataFilePath === undefined) authDataFilePath = path.resolve('.test_auth.json');\n return authDataFilePath;\n}\n\nexport function getTestConfig(): TestConfig {\n let conf: Partial<TestConfig> = {};\n if (fs.existsSync(CONFIG_FILE))\n conf = JSON.parse(fs.readFileSync(CONFIG_FILE, { encoding: 'utf-8' })) as TestConfig;\n\n if (process.env.PL_ADDRESS !== undefined) conf.address = process.env.PL_ADDRESS;\n\n if (process.env.PL_TEST_USER !== undefined) conf.test_user = process.env.PL_TEST_USER;\n\n if (process.env.PL_TEST_PASSWORD !== undefined) conf.test_password = process.env.PL_TEST_PASSWORD;\n\n if (process.env.PL_TEST_PROXY !== undefined) conf.test_proxy = process.env.PL_TEST_PROXY;\n\n if (conf.address === undefined)\n throw new Error(\n `can't resolve platform address (checked ${CONFIG_FILE} file and PL_ADDRESS environment var)`,\n );\n\n return conf as TestConfig;\n}\n\ninterface AuthCache {\n /** To check if config changed */\n conf: TestConfig;\n expiration: number;\n authInformation: AuthInformation;\n}\n\nfunction saveAuthInfoCallback(tConf: TestConfig): (authInformation: AuthInformation) => void {\n return (authInformation) => {\n const dst = getFullAuthDataFilePath();\n const tmpDst = getFullAuthDataFilePath() + randomUUID();\n fs.writeFileSync(\n tmpDst,\n Buffer.from(\n JSON.stringify({\n conf: tConf,\n authInformation,\n expiration: inferAuthRefreshTime(authInformation, 24 * 60 * 60),\n } as AuthCache),\n ),\n 'utf8',\n );\n fs.renameSync(tmpDst, dst);\n };\n}\n\nconst cleanAuthInfoCallback = () => {\n console.warn(`Removing: ${getFullAuthDataFilePath()}`);\n fs.rmSync(getFullAuthDataFilePath());\n};\n\nexport async function getTestClientConf(): Promise<{ conf: PlClientConfig; auth: AuthOps }> {\n const tConf = getTestConfig();\n\n let authInformation: AuthInformation | undefined = undefined;\n\n // try recover from cache\n if (fs.existsSync(getFullAuthDataFilePath())) {\n try {\n const cache: AuthCache = JSON.parse(\n fs.readFileSync(getFullAuthDataFilePath(), { encoding: 'utf-8' }),\n ) as AuthCache; // TODO runtime validation\n if (\n cache.conf.address === tConf.address\n && cache.conf.test_user === tConf.test_user\n && cache.conf.test_password === tConf.test_password\n && cache.expiration > Date.now()\n )\n authInformation = cache.authInformation;\n } catch (_e) {\n // removing cache file on any error\n fs.rmSync(getFullAuthDataFilePath());\n }\n }\n\n const plConf = plAddressToConfig(tConf.address);\n\n const uClient = new UnauthenticatedPlClient(plConf);\n\n const requireAuth = await uClient.requireAuth();\n\n if (!requireAuth && (tConf.test_user !== undefined || tConf.test_password !== undefined))\n throw new Error(\n `Server require no auth, but test user name or test password are provided via (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (requireAuth && (tConf.test_user === undefined || tConf.test_password === undefined))\n throw new Error(\n `No auth information found in config (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (authInformation === undefined) {\n if (requireAuth) authInformation = await uClient.login(tConf.test_user!, tConf.test_password!);\n // No authorization is required\n else authInformation = {};\n\n // saving cache\n saveAuthInfoCallback(tConf)(authInformation);\n }\n\n return {\n conf: plConf,\n auth: {\n authInformation,\n onUpdate: saveAuthInfoCallback(tConf),\n onAuthError: cleanAuthInfoCallback,\n onUpdateError: cleanAuthInfoCallback,\n },\n };\n}\n\nexport async function getTestLLClient(confOverrides: Partial<PlClientConfig> = {}) {\n const { conf, auth } = await getTestClientConf();\n return new LLPlClient({ ...conf, ...confOverrides }, { auth });\n}\n\nexport async function getTestClient(\n alternativeRoot?: string,\n confOverrides: Partial<PlClientConfig> = {},\n) {\n const { conf, auth } = await getTestClientConf();\n if (alternativeRoot !== undefined && conf.alternativeRoot !== undefined)\n throw new Error('test pl address configured with alternative root');\n return await PlClient.init({ ...conf, ...confOverrides, alternativeRoot }, auth);\n}\n\nexport type WithTempRootOptions = {\n /** If true and PL_ADDRESS is http://localhost or http://127.0.0.1:<port>,\n * a TCP proxy will be started and PL client will connect through it. */\n viaTcpProxy: true;\n /** Artificial latency for proxy (ms). Default 0 */\n proxyLatencyMs?: number;\n} | {\n viaTcpProxy?: undefined;\n};\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient) => Promise<T>\n): Promise<T | void>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: Awaited<ReturnType<typeof startTcpProxy>>) => Promise<T>,\n options: {\n viaTcpProxy: true;\n proxyLatencyMs?: number;\n },\n): Promise<T>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: any) => Promise<T>,\n options: WithTempRootOptions = {},\n): Promise<T | undefined> {\n const alternativeRoot = `test_${Date.now()}_${randomUUID()}`;\n let altRootId: OptionalResourceId = NullResourceId;\n // Proxy management\n let proxy: Awaited<ReturnType<typeof startTcpProxy>> | undefined;\n let confOverrides: Partial<PlClientConfig> = {};\n try {\n // Optionally start TCP proxy and rewrite PL_ADDRESS to point to proxy\n if (options.viaTcpProxy === true && process.env.PL_ADDRESS) {\n try {\n const url = new URL(process.env.PL_ADDRESS);\n const isHttp = url.protocol === 'http:';\n const isLocal = url.hostname === '127.0.0.1' || url.hostname === 'localhost';\n const port = parseInt(url.port);\n if (isHttp && isLocal && Number.isFinite(port)) {\n proxy = await startTcpProxy({ targetPort: port, latency: options.proxyLatencyMs ?? 0 });\n // Override client connection host:port to proxy\n confOverrides = { hostAndPort: `127.0.0.1:${proxy.port}` } as Partial<PlClientConfig>;\n } else {\n console.warn('*** skipping proxy-based test, PL_ADDRESS is not localhost', process.env.PL_ADDRESS);\n return;\n }\n } catch (_e) {\n // ignore proxy setup errors; tests will run against original address\n }\n }\n\n const client = await getTestClient(alternativeRoot, confOverrides);\n altRootId = client.clientRoot;\n console.log('altRootId', altRootId, altRootId.toString(16));\n const value = await body(client, proxy);\n const rawClient = await getTestClient();\n try {\n await rawClient.deleteAlternativeRoot(alternativeRoot);\n } catch (cleanupErr: any) {\n // Cleanup may fail if test intentionally deleted resources\n console.warn(`Failed to clean up alternative root ${alternativeRoot}:`, cleanupErr.message);\n }\n return value;\n } catch (err: any) {\n console.log('ERROR stack trace:', err.stack);\n console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);\n throw err;\n // throw new Error('withTempRoot error: ' + err.message, { cause: err });\n } finally {\n // Stop proxy if started\n if (proxy) {\n try {\n await proxy.disconnectAll();\n } catch (_e) { /* ignore */ }\n try {\n await new Promise<void>((resolve) => proxy!.server.close(() => resolve()));\n } catch (_e) { /* ignore */ }\n }\n }\n}\n"],"names":["path","fs","randomUUID","inferAuthRefreshTime","plAddressToConfig","UnauthenticatedPlClient","LLPlClient","PlClient","NullResourceId","startTcpProxy","resourceIdToString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"test_config.cjs","sources":["../../src/test/test_config.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport { LLPlClient } from '../core/ll_client';\nimport type { AuthInformation, AuthOps, PlClientConfig } from '../core/config';\nimport { plAddressToConfig } from '../core/config';\nimport { UnauthenticatedPlClient } from '../core/unauth_client';\nimport { PlClient } from '../core/client';\nimport { randomUUID } from 'node:crypto';\nimport type { OptionalResourceId } from '../core/types';\nimport { NullResourceId, resourceIdToString } from '../core/types';\nimport { inferAuthRefreshTime } from '../core/auth';\nimport * as path from 'node:path';\nimport type { TestTcpProxy } from './tcp-proxy';\nimport { startTcpProxy } from './tcp-proxy';\n\nexport {\n TestTcpProxy,\n};\n\nexport interface TestConfig {\n address: string;\n test_proxy?: string;\n test_user?: string;\n test_password?: string;\n}\n\nconst CONFIG_FILE = 'test_config.json';\n// const AUTH_DATA_FILE = '.test_auth.json';\n\nlet authDataFilePath: string | undefined;\n\nfunction getFullAuthDataFilePath() {\n if (authDataFilePath === undefined) authDataFilePath = path.resolve('.test_auth.json');\n return authDataFilePath;\n}\n\nexport function getTestConfig(): TestConfig {\n let conf: Partial<TestConfig> = {};\n if (fs.existsSync(CONFIG_FILE))\n conf = JSON.parse(fs.readFileSync(CONFIG_FILE, { encoding: 'utf-8' })) as TestConfig;\n\n if (process.env.PL_ADDRESS !== undefined) conf.address = process.env.PL_ADDRESS;\n\n if (process.env.PL_TEST_USER !== undefined) conf.test_user = process.env.PL_TEST_USER;\n\n if (process.env.PL_TEST_PASSWORD !== undefined) conf.test_password = process.env.PL_TEST_PASSWORD;\n\n if (process.env.PL_TEST_PROXY !== undefined) conf.test_proxy = process.env.PL_TEST_PROXY;\n\n if (conf.address === undefined)\n throw new Error(\n `can't resolve platform address (checked ${CONFIG_FILE} file and PL_ADDRESS environment var)`,\n );\n\n return conf as TestConfig;\n}\n\ninterface AuthCache {\n /** To check if config changed */\n conf: TestConfig;\n expiration: number;\n authInformation: AuthInformation;\n}\n\nfunction saveAuthInfoCallback(tConf: TestConfig): (authInformation: AuthInformation) => void {\n return (authInformation) => {\n const dst = getFullAuthDataFilePath();\n const tmpDst = getFullAuthDataFilePath() + randomUUID();\n fs.writeFileSync(\n tmpDst,\n Buffer.from(\n JSON.stringify({\n conf: tConf,\n authInformation,\n expiration: inferAuthRefreshTime(authInformation, 24 * 60 * 60),\n } as AuthCache),\n ),\n 'utf8',\n );\n fs.renameSync(tmpDst, dst);\n };\n}\n\nconst cleanAuthInfoCallback = () => {\n console.warn(`Removing: ${getFullAuthDataFilePath()}`);\n fs.rmSync(getFullAuthDataFilePath());\n};\n\nexport async function getTestClientConf(): Promise<{ conf: PlClientConfig; auth: AuthOps }> {\n const tConf = getTestConfig();\n\n let authInformation: AuthInformation | undefined = undefined;\n\n // try recover from cache\n if (fs.existsSync(getFullAuthDataFilePath())) {\n try {\n const cache: AuthCache = JSON.parse(\n fs.readFileSync(getFullAuthDataFilePath(), { encoding: 'utf-8' }),\n ) as AuthCache; // TODO runtime validation\n if (\n cache.conf.address === tConf.address\n && cache.conf.test_user === tConf.test_user\n && cache.conf.test_password === tConf.test_password\n && cache.expiration > Date.now()\n )\n authInformation = cache.authInformation;\n } catch (_e) {\n // removing cache file on any error\n fs.rmSync(getFullAuthDataFilePath());\n }\n }\n\n const plConf = plAddressToConfig(tConf.address);\n\n const uClient = new UnauthenticatedPlClient(plConf);\n\n const requireAuth = await uClient.requireAuth();\n\n if (!requireAuth && (tConf.test_user !== undefined || tConf.test_password !== undefined))\n throw new Error(\n `Server require no auth, but test user name or test password are provided via (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (requireAuth && (tConf.test_user === undefined || tConf.test_password === undefined))\n throw new Error(\n `No auth information found in config (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (authInformation === undefined) {\n if (requireAuth) authInformation = await uClient.login(tConf.test_user!, tConf.test_password!);\n // No authorization is required\n else authInformation = {};\n\n // saving cache\n saveAuthInfoCallback(tConf)(authInformation);\n }\n\n return {\n conf: plConf,\n auth: {\n authInformation,\n onUpdate: saveAuthInfoCallback(tConf),\n onAuthError: cleanAuthInfoCallback,\n onUpdateError: cleanAuthInfoCallback,\n },\n };\n}\n\nexport async function getTestLLClient(confOverrides: Partial<PlClientConfig> = {}) {\n const { conf, auth } = await getTestClientConf();\n return new LLPlClient({ ...conf, ...confOverrides }, { auth });\n}\n\nexport async function getTestClient(\n alternativeRoot?: string,\n confOverrides: Partial<PlClientConfig> = {},\n) {\n const { conf, auth } = await getTestClientConf();\n if (alternativeRoot !== undefined && conf.alternativeRoot !== undefined)\n throw new Error('test pl address configured with alternative root');\n return await PlClient.init({ ...conf, ...confOverrides, alternativeRoot }, auth);\n}\n\nexport type WithTempRootOptions = {\n /** If true and PL_ADDRESS is http://localhost or http://127.0.0.1:<port>,\n * a TCP proxy will be started and PL client will connect through it. */\n viaTcpProxy: true;\n /** Artificial latency for proxy (ms). Default 0 */\n proxyLatencyMs?: number;\n} | {\n viaTcpProxy?: undefined;\n};\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient) => Promise<T>\n): Promise<T | void>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: Awaited<ReturnType<typeof startTcpProxy>>) => Promise<T>,\n options: {\n viaTcpProxy: true;\n proxyLatencyMs?: number;\n },\n): Promise<T>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: any) => Promise<T>,\n options: WithTempRootOptions = {},\n): Promise<T | undefined> {\n const alternativeRoot = `test_${Date.now()}_${randomUUID()}`;\n let altRootId: OptionalResourceId = NullResourceId;\n // Proxy management\n let proxy: Awaited<ReturnType<typeof startTcpProxy>> | undefined;\n let confOverrides: Partial<PlClientConfig> = {};\n try {\n // Optionally start TCP proxy and rewrite PL_ADDRESS to point to proxy\n if (options.viaTcpProxy === true && process.env.PL_ADDRESS) {\n try {\n const url = new URL(process.env.PL_ADDRESS);\n const isHttp = url.protocol === 'http:';\n const isLocal = url.hostname === '127.0.0.1' || url.hostname === 'localhost';\n const port = parseInt(url.port);\n if (isHttp && isLocal && Number.isFinite(port)) {\n proxy = await startTcpProxy({ targetPort: port, latency: options.proxyLatencyMs ?? 0 });\n // Override client connection host:port to proxy\n confOverrides = { hostAndPort: `127.0.0.1:${proxy.port}` } as Partial<PlClientConfig>;\n } else {\n console.warn('*** skipping proxy-based test, PL_ADDRESS is not localhost', process.env.PL_ADDRESS);\n return;\n }\n } catch (_e) {\n // ignore proxy setup errors; tests will run against original address\n }\n }\n\n const client = await getTestClient(alternativeRoot, confOverrides);\n altRootId = client.clientRoot;\n const value = await body(client, proxy);\n const rawClient = await getTestClient();\n try {\n await rawClient.deleteAlternativeRoot(alternativeRoot);\n } catch (cleanupErr: any) {\n // Cleanup may fail if test intentionally deleted resources\n console.warn(`Failed to clean up alternative root ${alternativeRoot}:`, cleanupErr.message);\n }\n return value;\n } catch (err: any) {\n console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);\n throw err;\n // throw new Error('withTempRoot error: ' + err.message, { cause: err });\n } finally {\n // Stop proxy if started\n if (proxy) {\n try {\n await proxy.disconnectAll();\n } catch (_e) { /* ignore */ }\n try {\n await new Promise<void>((resolve) => proxy!.server.close(() => resolve()));\n } catch (_e) { /* ignore */ }\n }\n }\n}\n"],"names":["path","fs","randomUUID","inferAuthRefreshTime","plAddressToConfig","UnauthenticatedPlClient","LLPlClient","PlClient","NullResourceId","startTcpProxy","resourceIdToString"],"mappings":"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"}
|
package/dist/test/test_config.js
CHANGED
|
@@ -133,7 +133,6 @@ async function withTempRoot(body, options = {}) {
|
|
|
133
133
|
}
|
|
134
134
|
const client = await getTestClient(alternativeRoot, confOverrides);
|
|
135
135
|
altRootId = client.clientRoot;
|
|
136
|
-
console.log('altRootId', altRootId, altRootId.toString(16));
|
|
137
136
|
const value = await body(client, proxy);
|
|
138
137
|
const rawClient = await getTestClient();
|
|
139
138
|
try {
|
|
@@ -146,7 +145,6 @@ async function withTempRoot(body, options = {}) {
|
|
|
146
145
|
return value;
|
|
147
146
|
}
|
|
148
147
|
catch (err) {
|
|
149
|
-
console.log('ERROR stack trace:', err.stack);
|
|
150
148
|
console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);
|
|
151
149
|
throw err;
|
|
152
150
|
// throw new Error('withTempRoot error: ' + err.message, { cause: err });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test_config.js","sources":["../../src/test/test_config.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport { LLPlClient } from '../core/ll_client';\nimport type { AuthInformation, AuthOps, PlClientConfig } from '../core/config';\nimport { plAddressToConfig } from '../core/config';\nimport { UnauthenticatedPlClient } from '../core/unauth_client';\nimport { PlClient } from '../core/client';\nimport { randomUUID } from 'node:crypto';\nimport type { OptionalResourceId } from '../core/types';\nimport { NullResourceId, resourceIdToString } from '../core/types';\nimport { inferAuthRefreshTime } from '../core/auth';\nimport * as path from 'node:path';\nimport type { TestTcpProxy } from './tcp-proxy';\nimport { startTcpProxy } from './tcp-proxy';\n\nexport {\n TestTcpProxy,\n};\n\nexport interface TestConfig {\n address: string;\n test_proxy?: string;\n test_user?: string;\n test_password?: string;\n}\n\nconst CONFIG_FILE = 'test_config.json';\n// const AUTH_DATA_FILE = '.test_auth.json';\n\nlet authDataFilePath: string | undefined;\n\nfunction getFullAuthDataFilePath() {\n if (authDataFilePath === undefined) authDataFilePath = path.resolve('.test_auth.json');\n return authDataFilePath;\n}\n\nexport function getTestConfig(): TestConfig {\n let conf: Partial<TestConfig> = {};\n if (fs.existsSync(CONFIG_FILE))\n conf = JSON.parse(fs.readFileSync(CONFIG_FILE, { encoding: 'utf-8' })) as TestConfig;\n\n if (process.env.PL_ADDRESS !== undefined) conf.address = process.env.PL_ADDRESS;\n\n if (process.env.PL_TEST_USER !== undefined) conf.test_user = process.env.PL_TEST_USER;\n\n if (process.env.PL_TEST_PASSWORD !== undefined) conf.test_password = process.env.PL_TEST_PASSWORD;\n\n if (process.env.PL_TEST_PROXY !== undefined) conf.test_proxy = process.env.PL_TEST_PROXY;\n\n if (conf.address === undefined)\n throw new Error(\n `can't resolve platform address (checked ${CONFIG_FILE} file and PL_ADDRESS environment var)`,\n );\n\n return conf as TestConfig;\n}\n\ninterface AuthCache {\n /** To check if config changed */\n conf: TestConfig;\n expiration: number;\n authInformation: AuthInformation;\n}\n\nfunction saveAuthInfoCallback(tConf: TestConfig): (authInformation: AuthInformation) => void {\n return (authInformation) => {\n const dst = getFullAuthDataFilePath();\n const tmpDst = getFullAuthDataFilePath() + randomUUID();\n fs.writeFileSync(\n tmpDst,\n Buffer.from(\n JSON.stringify({\n conf: tConf,\n authInformation,\n expiration: inferAuthRefreshTime(authInformation, 24 * 60 * 60),\n } as AuthCache),\n ),\n 'utf8',\n );\n fs.renameSync(tmpDst, dst);\n };\n}\n\nconst cleanAuthInfoCallback = () => {\n console.warn(`Removing: ${getFullAuthDataFilePath()}`);\n fs.rmSync(getFullAuthDataFilePath());\n};\n\nexport async function getTestClientConf(): Promise<{ conf: PlClientConfig; auth: AuthOps }> {\n const tConf = getTestConfig();\n\n let authInformation: AuthInformation | undefined = undefined;\n\n // try recover from cache\n if (fs.existsSync(getFullAuthDataFilePath())) {\n try {\n const cache: AuthCache = JSON.parse(\n fs.readFileSync(getFullAuthDataFilePath(), { encoding: 'utf-8' }),\n ) as AuthCache; // TODO runtime validation\n if (\n cache.conf.address === tConf.address\n && cache.conf.test_user === tConf.test_user\n && cache.conf.test_password === tConf.test_password\n && cache.expiration > Date.now()\n )\n authInformation = cache.authInformation;\n } catch (_e) {\n // removing cache file on any error\n fs.rmSync(getFullAuthDataFilePath());\n }\n }\n\n const plConf = plAddressToConfig(tConf.address);\n\n const uClient = new UnauthenticatedPlClient(plConf);\n\n const requireAuth = await uClient.requireAuth();\n\n if (!requireAuth && (tConf.test_user !== undefined || tConf.test_password !== undefined))\n throw new Error(\n `Server require no auth, but test user name or test password are provided via (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (requireAuth && (tConf.test_user === undefined || tConf.test_password === undefined))\n throw new Error(\n `No auth information found in config (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (authInformation === undefined) {\n if (requireAuth) authInformation = await uClient.login(tConf.test_user!, tConf.test_password!);\n // No authorization is required\n else authInformation = {};\n\n // saving cache\n saveAuthInfoCallback(tConf)(authInformation);\n }\n\n return {\n conf: plConf,\n auth: {\n authInformation,\n onUpdate: saveAuthInfoCallback(tConf),\n onAuthError: cleanAuthInfoCallback,\n onUpdateError: cleanAuthInfoCallback,\n },\n };\n}\n\nexport async function getTestLLClient(confOverrides: Partial<PlClientConfig> = {}) {\n const { conf, auth } = await getTestClientConf();\n return new LLPlClient({ ...conf, ...confOverrides }, { auth });\n}\n\nexport async function getTestClient(\n alternativeRoot?: string,\n confOverrides: Partial<PlClientConfig> = {},\n) {\n const { conf, auth } = await getTestClientConf();\n if (alternativeRoot !== undefined && conf.alternativeRoot !== undefined)\n throw new Error('test pl address configured with alternative root');\n return await PlClient.init({ ...conf, ...confOverrides, alternativeRoot }, auth);\n}\n\nexport type WithTempRootOptions = {\n /** If true and PL_ADDRESS is http://localhost or http://127.0.0.1:<port>,\n * a TCP proxy will be started and PL client will connect through it. */\n viaTcpProxy: true;\n /** Artificial latency for proxy (ms). Default 0 */\n proxyLatencyMs?: number;\n} | {\n viaTcpProxy?: undefined;\n};\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient) => Promise<T>\n): Promise<T | void>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: Awaited<ReturnType<typeof startTcpProxy>>) => Promise<T>,\n options: {\n viaTcpProxy: true;\n proxyLatencyMs?: number;\n },\n): Promise<T>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: any) => Promise<T>,\n options: WithTempRootOptions = {},\n): Promise<T | undefined> {\n const alternativeRoot = `test_${Date.now()}_${randomUUID()}`;\n let altRootId: OptionalResourceId = NullResourceId;\n // Proxy management\n let proxy: Awaited<ReturnType<typeof startTcpProxy>> | undefined;\n let confOverrides: Partial<PlClientConfig> = {};\n try {\n // Optionally start TCP proxy and rewrite PL_ADDRESS to point to proxy\n if (options.viaTcpProxy === true && process.env.PL_ADDRESS) {\n try {\n const url = new URL(process.env.PL_ADDRESS);\n const isHttp = url.protocol === 'http:';\n const isLocal = url.hostname === '127.0.0.1' || url.hostname === 'localhost';\n const port = parseInt(url.port);\n if (isHttp && isLocal && Number.isFinite(port)) {\n proxy = await startTcpProxy({ targetPort: port, latency: options.proxyLatencyMs ?? 0 });\n // Override client connection host:port to proxy\n confOverrides = { hostAndPort: `127.0.0.1:${proxy.port}` } as Partial<PlClientConfig>;\n } else {\n console.warn('*** skipping proxy-based test, PL_ADDRESS is not localhost', process.env.PL_ADDRESS);\n return;\n }\n } catch (_e) {\n // ignore proxy setup errors; tests will run against original address\n }\n }\n\n const client = await getTestClient(alternativeRoot, confOverrides);\n altRootId = client.clientRoot;\n console.log('altRootId', altRootId, altRootId.toString(16));\n const value = await body(client, proxy);\n const rawClient = await getTestClient();\n try {\n await rawClient.deleteAlternativeRoot(alternativeRoot);\n } catch (cleanupErr: any) {\n // Cleanup may fail if test intentionally deleted resources\n console.warn(`Failed to clean up alternative root ${alternativeRoot}:`, cleanupErr.message);\n }\n return value;\n } catch (err: any) {\n console.log('ERROR stack trace:', err.stack);\n console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);\n throw err;\n // throw new Error('withTempRoot error: ' + err.message, { cause: err });\n } finally {\n // Stop proxy if started\n if (proxy) {\n try {\n await proxy.disconnectAll();\n } catch (_e) { /* ignore */ }\n try {\n await new Promise<void>((resolve) => proxy!.server.close(() => resolve()));\n } catch (_e) { /* ignore */ }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"test_config.js","sources":["../../src/test/test_config.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport { LLPlClient } from '../core/ll_client';\nimport type { AuthInformation, AuthOps, PlClientConfig } from '../core/config';\nimport { plAddressToConfig } from '../core/config';\nimport { UnauthenticatedPlClient } from '../core/unauth_client';\nimport { PlClient } from '../core/client';\nimport { randomUUID } from 'node:crypto';\nimport type { OptionalResourceId } from '../core/types';\nimport { NullResourceId, resourceIdToString } from '../core/types';\nimport { inferAuthRefreshTime } from '../core/auth';\nimport * as path from 'node:path';\nimport type { TestTcpProxy } from './tcp-proxy';\nimport { startTcpProxy } from './tcp-proxy';\n\nexport {\n TestTcpProxy,\n};\n\nexport interface TestConfig {\n address: string;\n test_proxy?: string;\n test_user?: string;\n test_password?: string;\n}\n\nconst CONFIG_FILE = 'test_config.json';\n// const AUTH_DATA_FILE = '.test_auth.json';\n\nlet authDataFilePath: string | undefined;\n\nfunction getFullAuthDataFilePath() {\n if (authDataFilePath === undefined) authDataFilePath = path.resolve('.test_auth.json');\n return authDataFilePath;\n}\n\nexport function getTestConfig(): TestConfig {\n let conf: Partial<TestConfig> = {};\n if (fs.existsSync(CONFIG_FILE))\n conf = JSON.parse(fs.readFileSync(CONFIG_FILE, { encoding: 'utf-8' })) as TestConfig;\n\n if (process.env.PL_ADDRESS !== undefined) conf.address = process.env.PL_ADDRESS;\n\n if (process.env.PL_TEST_USER !== undefined) conf.test_user = process.env.PL_TEST_USER;\n\n if (process.env.PL_TEST_PASSWORD !== undefined) conf.test_password = process.env.PL_TEST_PASSWORD;\n\n if (process.env.PL_TEST_PROXY !== undefined) conf.test_proxy = process.env.PL_TEST_PROXY;\n\n if (conf.address === undefined)\n throw new Error(\n `can't resolve platform address (checked ${CONFIG_FILE} file and PL_ADDRESS environment var)`,\n );\n\n return conf as TestConfig;\n}\n\ninterface AuthCache {\n /** To check if config changed */\n conf: TestConfig;\n expiration: number;\n authInformation: AuthInformation;\n}\n\nfunction saveAuthInfoCallback(tConf: TestConfig): (authInformation: AuthInformation) => void {\n return (authInformation) => {\n const dst = getFullAuthDataFilePath();\n const tmpDst = getFullAuthDataFilePath() + randomUUID();\n fs.writeFileSync(\n tmpDst,\n Buffer.from(\n JSON.stringify({\n conf: tConf,\n authInformation,\n expiration: inferAuthRefreshTime(authInformation, 24 * 60 * 60),\n } as AuthCache),\n ),\n 'utf8',\n );\n fs.renameSync(tmpDst, dst);\n };\n}\n\nconst cleanAuthInfoCallback = () => {\n console.warn(`Removing: ${getFullAuthDataFilePath()}`);\n fs.rmSync(getFullAuthDataFilePath());\n};\n\nexport async function getTestClientConf(): Promise<{ conf: PlClientConfig; auth: AuthOps }> {\n const tConf = getTestConfig();\n\n let authInformation: AuthInformation | undefined = undefined;\n\n // try recover from cache\n if (fs.existsSync(getFullAuthDataFilePath())) {\n try {\n const cache: AuthCache = JSON.parse(\n fs.readFileSync(getFullAuthDataFilePath(), { encoding: 'utf-8' }),\n ) as AuthCache; // TODO runtime validation\n if (\n cache.conf.address === tConf.address\n && cache.conf.test_user === tConf.test_user\n && cache.conf.test_password === tConf.test_password\n && cache.expiration > Date.now()\n )\n authInformation = cache.authInformation;\n } catch (_e) {\n // removing cache file on any error\n fs.rmSync(getFullAuthDataFilePath());\n }\n }\n\n const plConf = plAddressToConfig(tConf.address);\n\n const uClient = new UnauthenticatedPlClient(plConf);\n\n const requireAuth = await uClient.requireAuth();\n\n if (!requireAuth && (tConf.test_user !== undefined || tConf.test_password !== undefined))\n throw new Error(\n `Server require no auth, but test user name or test password are provided via (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (requireAuth && (tConf.test_user === undefined || tConf.test_password === undefined))\n throw new Error(\n `No auth information found in config (${CONFIG_FILE}) or env variables: PL_TEST_USER and PL_TEST_PASSWORD`,\n );\n\n if (authInformation === undefined) {\n if (requireAuth) authInformation = await uClient.login(tConf.test_user!, tConf.test_password!);\n // No authorization is required\n else authInformation = {};\n\n // saving cache\n saveAuthInfoCallback(tConf)(authInformation);\n }\n\n return {\n conf: plConf,\n auth: {\n authInformation,\n onUpdate: saveAuthInfoCallback(tConf),\n onAuthError: cleanAuthInfoCallback,\n onUpdateError: cleanAuthInfoCallback,\n },\n };\n}\n\nexport async function getTestLLClient(confOverrides: Partial<PlClientConfig> = {}) {\n const { conf, auth } = await getTestClientConf();\n return new LLPlClient({ ...conf, ...confOverrides }, { auth });\n}\n\nexport async function getTestClient(\n alternativeRoot?: string,\n confOverrides: Partial<PlClientConfig> = {},\n) {\n const { conf, auth } = await getTestClientConf();\n if (alternativeRoot !== undefined && conf.alternativeRoot !== undefined)\n throw new Error('test pl address configured with alternative root');\n return await PlClient.init({ ...conf, ...confOverrides, alternativeRoot }, auth);\n}\n\nexport type WithTempRootOptions = {\n /** If true and PL_ADDRESS is http://localhost or http://127.0.0.1:<port>,\n * a TCP proxy will be started and PL client will connect through it. */\n viaTcpProxy: true;\n /** Artificial latency for proxy (ms). Default 0 */\n proxyLatencyMs?: number;\n} | {\n viaTcpProxy?: undefined;\n};\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient) => Promise<T>\n): Promise<T | void>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: Awaited<ReturnType<typeof startTcpProxy>>) => Promise<T>,\n options: {\n viaTcpProxy: true;\n proxyLatencyMs?: number;\n },\n): Promise<T>;\n\nexport async function withTempRoot<T>(\n body: (pl: PlClient, proxy: any) => Promise<T>,\n options: WithTempRootOptions = {},\n): Promise<T | undefined> {\n const alternativeRoot = `test_${Date.now()}_${randomUUID()}`;\n let altRootId: OptionalResourceId = NullResourceId;\n // Proxy management\n let proxy: Awaited<ReturnType<typeof startTcpProxy>> | undefined;\n let confOverrides: Partial<PlClientConfig> = {};\n try {\n // Optionally start TCP proxy and rewrite PL_ADDRESS to point to proxy\n if (options.viaTcpProxy === true && process.env.PL_ADDRESS) {\n try {\n const url = new URL(process.env.PL_ADDRESS);\n const isHttp = url.protocol === 'http:';\n const isLocal = url.hostname === '127.0.0.1' || url.hostname === 'localhost';\n const port = parseInt(url.port);\n if (isHttp && isLocal && Number.isFinite(port)) {\n proxy = await startTcpProxy({ targetPort: port, latency: options.proxyLatencyMs ?? 0 });\n // Override client connection host:port to proxy\n confOverrides = { hostAndPort: `127.0.0.1:${proxy.port}` } as Partial<PlClientConfig>;\n } else {\n console.warn('*** skipping proxy-based test, PL_ADDRESS is not localhost', process.env.PL_ADDRESS);\n return;\n }\n } catch (_e) {\n // ignore proxy setup errors; tests will run against original address\n }\n }\n\n const client = await getTestClient(alternativeRoot, confOverrides);\n altRootId = client.clientRoot;\n const value = await body(client, proxy);\n const rawClient = await getTestClient();\n try {\n await rawClient.deleteAlternativeRoot(alternativeRoot);\n } catch (cleanupErr: any) {\n // Cleanup may fail if test intentionally deleted resources\n console.warn(`Failed to clean up alternative root ${alternativeRoot}:`, cleanupErr.message);\n }\n return value;\n } catch (err: any) {\n console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);\n throw err;\n // throw new Error('withTempRoot error: ' + err.message, { cause: err });\n } finally {\n // Stop proxy if started\n if (proxy) {\n try {\n await proxy.disconnectAll();\n } catch (_e) { /* ignore */ }\n try {\n await new Promise<void>((resolve) => proxy!.server.close(() => resolve()));\n } catch (_e) { /* ignore */ }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-client",
|
|
3
|
-
"version": "2.16.
|
|
3
|
+
"version": "2.16.5",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22.19.0"
|
|
6
6
|
},
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"utility-types": "^3.11.0",
|
|
36
36
|
"yaml": "^2.8.0",
|
|
37
37
|
"@milaboratories/pl-http": "1.2.0",
|
|
38
|
-
"@milaboratories/
|
|
39
|
-
"@milaboratories/
|
|
38
|
+
"@milaboratories/ts-helpers": "1.5.3",
|
|
39
|
+
"@milaboratories/pl-model-common": "1.21.5"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@protobuf-ts/plugin": "2.11.1",
|
|
@@ -5,7 +5,7 @@ import { test, expect } from 'vitest';
|
|
|
5
5
|
import { sleep } from '@milaboratories/ts-helpers';
|
|
6
6
|
import { DisconnectedError } from './errors';
|
|
7
7
|
|
|
8
|
-
test('connectivity: disconnect', async () => {
|
|
8
|
+
test('connectivity: disconnect during tx', async () => {
|
|
9
9
|
await withTempRoot(async (pl, proxy) => {
|
|
10
10
|
await expect(async () => {
|
|
11
11
|
await pl.withWriteTx('resource1', async (tx) => {
|
|
@@ -21,7 +21,7 @@ test('connectivity: disconnect', async () => {
|
|
|
21
21
|
|
|
22
22
|
await proxy?.disconnectAll();
|
|
23
23
|
|
|
24
|
-
await sleep(
|
|
24
|
+
await sleep(1);
|
|
25
25
|
|
|
26
26
|
const theField1 = { resourceId: r1, fieldName: 'theField' };
|
|
27
27
|
tx.createField(theField1, 'Input');
|
package/src/test/tcp-proxy.ts
CHANGED
|
@@ -29,7 +29,7 @@ export async function startTcpProxy(options: TcpProxyOptions) {
|
|
|
29
29
|
|
|
30
30
|
const connections = new Set<{ socket: net.Socket; client: net.Socket }>();
|
|
31
31
|
|
|
32
|
-
async function disconnectAll() {
|
|
32
|
+
async function disconnectAll(delayMs: number | undefined = undefined) {
|
|
33
33
|
const kill = () => {
|
|
34
34
|
for (const { socket, client } of connections) {
|
|
35
35
|
if (!socket.destroyed) socket.destroy();
|
|
@@ -37,7 +37,7 @@ export async function startTcpProxy(options: TcpProxyOptions) {
|
|
|
37
37
|
}
|
|
38
38
|
connections.clear();
|
|
39
39
|
};
|
|
40
|
-
await timers.setTimeout(
|
|
40
|
+
if (delayMs !== undefined) await timers.setTimeout(delayMs);
|
|
41
41
|
kill();
|
|
42
42
|
};
|
|
43
43
|
|
|
@@ -91,7 +91,7 @@ export async function startTcpProxy(options: TcpProxyOptions) {
|
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
server.listen({ port: port ?? 0 }, () => {
|
|
94
|
-
console.log('
|
|
94
|
+
console.log('Test TCP proxy server started on', server.address());
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
// Wait for proxy to be ready
|
package/src/test/test_config.ts
CHANGED
|
@@ -214,7 +214,6 @@ export async function withTempRoot<T>(
|
|
|
214
214
|
|
|
215
215
|
const client = await getTestClient(alternativeRoot, confOverrides);
|
|
216
216
|
altRootId = client.clientRoot;
|
|
217
|
-
console.log('altRootId', altRootId, altRootId.toString(16));
|
|
218
217
|
const value = await body(client, proxy);
|
|
219
218
|
const rawClient = await getTestClient();
|
|
220
219
|
try {
|
|
@@ -225,7 +224,6 @@ export async function withTempRoot<T>(
|
|
|
225
224
|
}
|
|
226
225
|
return value;
|
|
227
226
|
} catch (err: any) {
|
|
228
|
-
console.log('ERROR stack trace:', err.stack);
|
|
229
227
|
console.log(`ALTERNATIVE ROOT: ${alternativeRoot} (${resourceIdToString(altRootId)})`);
|
|
230
228
|
throw err;
|
|
231
229
|
// throw new Error('withTempRoot error: ' + err.message, { cause: err });
|