#!/usr/bin/env node /** * 测试前置自检:**临时目录还有空间吗**。 * * 名字**不带 `.test.`** —— 所以它不会被 `node --test 'test/*.test.mjs'` 收进去 * 当用例跑;它由 `package.json` 的 `test` 脚本**先**跑一次。 * * # 它在挡什么 * * 2026-09-14 实测:`/tmp` 是 tmpfs,被别的项目/别的 agent 的东西占满, * `bavail` 只剩 0.70 MiB。此时 `npm test` 会红一条 * `★巨大的 message 行不进内存也不影响解析`(`ENOSPC`)—— 那条红**长得像内存缺陷**, * 而真相是环境不足。这个脚本把"环境不足"在**跑测试之前**就大声说出来。 * * # 退出码约定(与 `deploy/redeploy-plugin.sh` 同一套) * * 0 = 环境够用,继续跑测试 * 2 = **环境问题**(不是断言失败) * * 写清 `2` 的意义很关键:CI 或人看到 `1` 会去查代码,看到 `2` 才知道去查机器。 */ import { statfsSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { judgeSpace, MIN_FREE_BYTES } from '../lib/tmp-space.mjs'; /** 测量:进程**实际能写**的字节数。读不到返回 null(交给判据放行)。 */ function measureAvailBytes(dir) { try { if (typeof statfsSync !== 'function') return null; // Node < 18.15 const s = statfsSync(dir); if (!s || !s.bsize) return null; // 用 `bavail`(非特权进程可用的块数),**不是** `bfree`(含 root 保留块): // 这里回答的是"我写不写得进去",不是"机器上空闲多少"。 return s.bavail * s.bsize; } catch { return null; // 不知道 ≠ 不对 } } const dir = tmpdir(); const availBytes = measureAvailBytes(dir); const verdict = judgeSpace({ availBytes }); if (verdict.ok) { console.log(`[env-preflight] 临时目录 ${dir}:${verdict.note}`); process.exit(0); } console.error(` [env-preflight] 环境不足:临时目录写不下,**这不是断言失败**。 目录 ${dir} 可用 ${(availBytes / 1048576).toFixed(1)} MiB 需要 ${(MIN_FREE_BYTES / 1048576).toFixed(1)} MiB 判定 ${verdict.note} 测试用例会往临时目录写十几 MiB 的文件。空间不够时它报的是 ENOSPC, 而那看起来像代码缺陷 —— 曾经就是这么误导过一次。 药方(任选其一): TMPDIR=<有空间的目录> npm test # 换临时目录,最省事 清理 ${dir} 下不属于你的东西之前先问主人 # 别误删别人的缓存 退出码 2 = 环境问题(与 deploy/redeploy-plugin.sh 的 2 同义),不是代码问题。 `); process.exit(2);