From ba10b0f66bde301b5526b63e423940131f1bbb4a Mon Sep 17 00:00:00 2001 From: hanafusay <65750817+hanafusay@users.noreply.github.com> Date: Tue, 4 Aug 2026 19:19:54 +0900 Subject: [PATCH] fix(dev): read readiness logs from byte offsets --- scripts/dev/supervisor/children.ts | 2 +- test/dev-supervisor-child.test.ts | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/scripts/dev/supervisor/children.ts b/scripts/dev/supervisor/children.ts index 5c81dbcff..ae2ef17ae 100644 --- a/scripts/dev/supervisor/children.ts +++ b/scripts/dev/supervisor/children.ts @@ -93,7 +93,7 @@ export class Child { if (this.spec.readiness.kind === "log") { const pattern = this.spec.readiness.pattern; const offset = this.logOffset; - const seen = bestEffortValue(() => readFileSync(this.logFile(), "utf8").slice(offset).includes(pattern)); + const seen = bestEffortValue(() => readFileSync(this.logFile()).includes(pattern, offset)); if (seen) return { ok: true }; } else { const url = this.spec.readiness.url; diff --git a/test/dev-supervisor-child.test.ts b/test/dev-supervisor-child.test.ts index 5f7c9c5cd..10223f843 100644 --- a/test/dev-supervisor-child.test.ts +++ b/test/dev-supervisor-child.test.ts @@ -1,6 +1,6 @@ import { test } from "node:test"; import assert from "node:assert/strict"; -import { mkdtempSync, rmSync } from "node:fs"; +import { mkdtempSync, rmSync, statSync, writeFileSync } from "node:fs"; import { createServer } from "node:net"; import { tmpdir } from "node:os"; import { join } from "node:path"; @@ -34,6 +34,28 @@ function spec(lock: string, port: number, extraArgs: string[] = []): ChildSpec { }; } +test("child finds log readiness after existing multibyte UTF-8 content", async () => { + const lock = mkdtempSync(join(tmpdir(), "qm-child-")); + const port = await freeTcpPort(); + const child = new Child( + spec(lock, port), + lock, + () => {}, + () => {}, + ); + const prefix = "以前の起動\n"; + writeFileSync(child.logFile(), prefix); + assert.equal(statSync(child.logFile()).size, Buffer.byteLength(prefix)); + + try { + const res = await child.start(); + assert.equal(res.ok, true, res.detail); + } finally { + await child.stop(); + rmSync(lock, { recursive: true, force: true }); + } +}); + test("child starts, reports ready via log pattern, and stops with the port released", async () => { const lock = mkdtempSync(join(tmpdir(), "qm-child-")); const port = await freeTcpPort();