fix(POSTV1-02): 补齐便携包Worker运行依赖
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
This commit is contained in:
@@ -5,6 +5,7 @@ import { existsSync } from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import { spawn } from "node:child_process";
|
||||
import { createServer } from "node:net";
|
||||
|
||||
const packageRoot = resolve(process.env.DADA_POSTV1_PACKAGE_ROOT ?? ".build/portable-release/Dada-P0A-0.0.0-win-x64");
|
||||
const port = 43121;
|
||||
@@ -43,6 +44,71 @@ async function stop(child) {
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyWorkerStartup(configPath) {
|
||||
const pipeName = `Dada.P0A.PostV1.${process.pid}.${Date.now()}`;
|
||||
const pipePath = `\\\\.\\pipe\\${pipeName}`;
|
||||
const server = createServer();
|
||||
await new Promise((resolveListen, rejectListen) => {
|
||||
server.once("error", rejectListen);
|
||||
server.listen(pipePath, resolveListen);
|
||||
});
|
||||
const child = spawn(join(packageRoot, "runtime", "node.exe"), [
|
||||
join(packageRoot, "server", "worker.mjs"),
|
||||
"--dada-control-pipe", pipeName,
|
||||
"--dada-credential-stdin",
|
||||
], {
|
||||
cwd: packageRoot,
|
||||
env: {
|
||||
...process.env,
|
||||
DADA_INSTANCE_CONFIG_PATH: configPath,
|
||||
DADA_SQLITE_NATIVE_BINDING: join(packageRoot, "server", "native", "better_sqlite3.node"),
|
||||
},
|
||||
stdio: ["pipe", "ignore", "ignore"],
|
||||
windowsHide: true,
|
||||
});
|
||||
child.stdin.end(JSON.stringify({ "Dada/P0A/worker/ai-gateway": "synthetic-runtime-token" }));
|
||||
try {
|
||||
await new Promise((resolveReady, rejectReady) => {
|
||||
let settled = false;
|
||||
const finish = (error) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(deadline);
|
||||
child.off("exit", onExit);
|
||||
if (error) rejectReady(error); else resolveReady();
|
||||
};
|
||||
const deadline = setTimeout(() => finish(new Error("packaged worker ready timeout")), 15_000);
|
||||
const onExit = (code) => finish(new Error(`packaged worker exited before ready: ${code}`));
|
||||
child.once("exit", onExit);
|
||||
server.once("connection", (connection) => {
|
||||
connection.setEncoding("utf8");
|
||||
let pending = "";
|
||||
connection.on("data", (chunk) => {
|
||||
pending += chunk;
|
||||
while (pending.includes("\n")) {
|
||||
const newline = pending.indexOf("\n");
|
||||
const status = pending.slice(0, newline).trim();
|
||||
pending = pending.slice(newline + 1);
|
||||
if (status === "storage_unavailable") finish(new Error("packaged worker reported storage_unavailable"));
|
||||
if (status === "ready") {
|
||||
setTimeout(() => {
|
||||
if (settled) return;
|
||||
connection.write("shutdown\n");
|
||||
finish();
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
const exitCode = await new Promise((resolveExit) => child.once("exit", resolveExit));
|
||||
assert.equal(exitCode, 0);
|
||||
} finally {
|
||||
if (child.exitCode === null) child.kill();
|
||||
await new Promise((resolveClose) => server.close(resolveClose));
|
||||
}
|
||||
}
|
||||
|
||||
test("portable package serves the product and keeps SQLite data across API restart", async () => {
|
||||
assert.ok(existsSync(join(packageRoot, "Dada.exe")));
|
||||
assert.ok(existsSync(join(packageRoot, "web", "index.html")));
|
||||
@@ -72,6 +138,7 @@ test("portable package serves the product and keeps SQLite data across API resta
|
||||
assert.match(await page.text(), /<div id="root"><\/div>/);
|
||||
}
|
||||
assert.ok(existsSync(join(dataRoot, "db", "dada.sqlite3")));
|
||||
await verifyWorkerStartup(configPath);
|
||||
} finally {
|
||||
await stop(api);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user