From 6e18f32a329a2336555c08843d6c27b74ca5017f Mon Sep 17 00:00:00 2001 From: arookieofc <2128194521@qq.com> Date: Sat, 7 Nov 2026 00:16:14 +0800 Subject: [PATCH] fix(smoke): wait for the server before deleting its data directory (#1858) The java smoke flakes on teardown: the run.test.ts afterEach kills openidea-server and immediately removes its home directory, but jdtls's JVM is still shutting down inside it, so rmdir fails ENOTEMPTY. Now close() resolves once the process exits, and the removal retries for ten seconds instead of one. --- smoke/run.test.ts | 8 +++++--- smoke/server.ts | 11 ++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/smoke/run.test.ts b/smoke/run.test.ts index d9b6c7274..7a46ec00e 100644 --- a/smoke/run.test.ts +++ b/smoke/run.test.ts @@ -128,12 +128,14 @@ let server: Server | null = null; let disconnect: (() => void) | null = null; let base = ""; -afterEach(() => { +afterEach(async () => { // As switching projects does: run ids restart with each server. resetRuns(); disconnect?.(); - server?.close(); - if (base) rmSync(base, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }); + await server?.close(); + // A language server's own process (jdtls's JVM) can outlive the server's for a moment: + // deleting its data directory has to wait for it. + if (base) rmSync(base, { recursive: true, force: true, maxRetries: 10, retryDelay: 1000 }); }); async function open(c: Case): Promise { diff --git a/smoke/server.ts b/smoke/server.ts index 241e8130a..af387c384 100644 --- a/smoke/server.ts +++ b/smoke/server.ts @@ -78,9 +78,14 @@ export class Server { } } - close() { - this.child.stdin.end(); - this.child.kill(); + /** Kills the server; resolves once the process is gone (its children may still be exiting). */ + async close(): Promise { + if (this.child.exitCode === null && !this.child.killed) { + const exited = new Promise((resolve) => this.child.once("exit", () => resolve())); + this.child.stdin.end(); + this.child.kill(); + await exited; + } } private request(method: string, params: unknown): Promise {