tests; fixes for ts process management

This commit is contained in:
Egor Aristov 2025-11-08 17:47:46 +03:00
parent da8401ce16
commit 1b794147ec
Signed by: egor3f
GPG Key ID: 40482A264AAEC85F
5 changed files with 19 additions and 4 deletions

View File

@ -15,7 +15,7 @@
}, },
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"test": "vitest run --teardown-timeout=20000 --test-timeout=20000" "test": "vitest run --teardown-timeout=20000 --test-timeout=20000 --sequence.concurrent"
}, },
"dependencies": { "dependencies": {
"@types/node": "^22.10.5" "@types/node": "^22.10.5"

View File

@ -6,3 +6,9 @@ test('test connection timeout', async ({expect}) => {
await parentIpc.start(); await parentIpc.start();
await expect(parentIpc.wait()).rejects.toThrowError('timed out'); await expect(parentIpc.wait()).rejects.toThrowError('timed out');
}); });
test('test process stop before connection accept', async ({expect}) => {
const parentIpc = new ParentIPC('testdata/sleep3.sh', []);
await parentIpc.start();
await expect(parentIpc.wait()).rejects.toThrowError('command exited before connection established');
});

View File

@ -45,6 +45,7 @@ abstract class IPCCommon {
protected pendingCalls: Record<number, (result: CallResult) => void> = {}; protected pendingCalls: Record<number, (result: CallResult) => void> = {};
protected stopRequested: boolean = false; protected stopRequested: boolean = false;
protected processingCalls: number = 0; protected processingCalls: number = 0;
protected ready = false;
protected errorQueue = new AsyncQueue<Error>(); protected errorQueue = new AsyncQueue<Error>();
protected onClose?: () => void; protected onClose?: () => void;
@ -84,6 +85,8 @@ abstract class IPCCommon {
this.raiseErr(new Error(`${ e }`)); this.raiseErr(new Error(`${ e }`));
} }
}); });
this.ready = true;
} }
protected processMsg(msg: Message): void { protected processMsg(msg: Message): void {
@ -266,11 +269,16 @@ export class ParentIPC extends IPCCommon {
async wait(): Promise<void> { async wait(): Promise<void> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
if (!this.cmd) throw new Error('Command is not started yet'); if (!this.cmd) {
reject('Command is not started yet');
return;
}
this.cmd.addListener('close', (code, signal) => { this.cmd.addListener('close', (code, signal) => {
if (signal || code) { if (signal || code) {
if (signal) reject(new Error(`Process exited with signal ${ signal }`)); if (signal) reject(new Error(`Process exited with signal ${ signal }`));
else reject(new Error(`Process exited with code ${ code }`)); else reject(new Error(`Process exited with code ${ code }`));
} else if(!this.ready) {
reject('command exited before connection established');
} else { } else {
resolve(); resolve();
} }

View File

@ -1,5 +1,3 @@
#!/usr/bin/env bash #!/usr/bin/env bash
echo sleeping...
sleep 15s sleep 15s
echo slept

3
lib/ts/testdata/sleep3.sh vendored Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
sleep 3s