diff --git a/plugins/pi-mail-bridge/test/env-guard.test.mjs b/plugins/pi-mail-bridge/test/env-guard.test.mjs index 2396328..6999ff9 100644 --- a/plugins/pi-mail-bridge/test/env-guard.test.mjs +++ b/plugins/pi-mail-bridge/test/env-guard.test.mjs @@ -115,37 +115,28 @@ test('端到端:退出码 2 与文案(两个方向都验,不依赖机器 assert.match(good.stdout, /env-preflight/); }); -test('★开关真的被认:按真实测量分叉,两个分支各有分辨力', () => { - // pi 评审指出上一版的漏洞:原来只在"真实测量不足"那个分支里断言, - // 机器一恢复健康(/tmp 被清空)这条就退化成"只验 --measure"的弱检查 —— - // 而它守的恰恰是"开关别静默失效"。 +test('★开关真的被认:两个探针必须给出**相反**的判定与相反的关键词', () => { + // pi 评审的漏洞一:上一版只在"真实测量不足"那个分支里断言 ⇒ 机器一恢复健康 + // (/tmp 被清空)这条就退化成弱检查,而它守的恰恰是"开关别静默失效"。 // - // 两个方向是**对偶**的,各守一个机器状态,所以按实测分叉、在两个分支里 - // 断言**相反**的方向 ⇒ 任何机器状态下都有分辨力,不会退化成弱检查: + // 漏洞二(我做变异时撞上的,比漏洞一更隐蔽):按"真实测量"分叉的写法本身留了一个 + // 短路分支 —— 本机真实可用就是 0 ⇒ 永远走不足分支,而那个分支只看退出码; + // 于是把开关**整个忽略掉**(永远用真实测量),断言**照样绿**。 + // "断言在,区分力不在" —— 与 pi 点的是同一类病,只是它藏在"跑不到的分支"里。 // - // 真实不足 ⇒ 注入大数必须放行 (若开关被忽略,回退测量 ⇒ 2 ≠ 0 ⇒ 红) - // 真实充足 ⇒ 注入 0 必须 exit 2(若开关被忽略,回退测量 ⇒ 0 ≠ 2 ⇒ 红) - // - // 判据红的方式不一样,但**红**这件事在两种机器状态下都成立。 - const measured = runPreflight(['--measure=/tmp']); - assert.equal(measured.status, 0, '--measure 只量一次并 exit 0'); - const m = /"availBytes":\s*(\d+|null)/.exec(measured.stdout); - assert.ok(m, `--measure 必须回一个数或 null,实际:${measured.stdout.trim()}`); + // 修法:**不跟真实测量比,让两个探针自己互为反面**,并断言**输出里的判定词** + // (不只看退出码 —— 退出码可能与真实状态巧合相同): + // 探针 A:注入 1 字节 ⇒ exit 2 + 必须打印「< 需要」 + // 探针 B:注入 128 MiB(>阈值)⇒ exit 0 + 必须打印「≥ 需要」 + // 若开关被忽略,两次都按**真实**测量给同一个答案 ⇒ 至少一条红。 + // 这个论证不依赖真实测量是多少。 + const tiny = runPreflight(['--inject-avail=1']); + assert.equal(tiny.status, 2, '注入 1 字节必须 exit 2'); + assert.match(tiny.stderr + tiny.stdout, /<\s*需要/, '必须打印「不足」的判定'); - if (m[1] === 'null') { - // 量不到就**不能**分叉(既不知道机器是哪种状态)。明说并让判据红, - // 而不是悄悄跳过 —— 跳过会把"失去分辨力"伪装成"验过了"。 - assert.fail('本机 /tmp 量不出可用空间,这条判据无法分叉 —— 别让它静默退化'); - } - const realAvail = Number(m[1]); - - if (realAvail < MIN_FREE_BYTES) { - const injected = runPreflight(['--inject-avail=999999999']); - assert.equal(injected.status, 0, '真实不足 + 注入充足 ⇒ 必须按注入的走(开关被认)'); - } else { - const injected = runPreflight(['--inject-avail=0']); - assert.equal(injected.status, 2, '真实充足 + 注入 0 ⇒ 必须按注入的走(开关被认)'); - } + const plenty = runPreflight(['--inject-avail=134217728']); + assert.equal(plenty.status, 0, '注入 128 MiB(> 32 MiB 阈值)必须放行'); + assert.match(plenty.stdout, /≥\s*需要/, '必须打印「充足」的判定(不是靠退出码近似)'); }); test('★非法参数必须炸(exit 2),不能静默放行', () => { @@ -159,7 +150,8 @@ test('★非法参数必须炸(exit 2),不能静默放行', () => { assert.equal(runPreflight(['--inject-avail=null']).status, 0, 'null 是合法值(没测到 ⇒ 放行)'); }); -test('测量层:读不到的目录 → null(这条判据不依赖机器状态,永远跑得了)', () => { // 覆盖"读不到 ⇒ null ⇒ 放行"那一支。端到端那条一旦被跳过,就只剩这条管它。 +test('测量层:读不到的目录 → null(这条判据不依赖机器状态,永远跑得了)', () => { + // 覆盖"读不到 ⇒ null ⇒ 放行"那一支。端到端那条一旦被跳过,就只剩这条管它。 assert.equal(measureAvailBytes('/definitely/not/here'), null); assert.equal(measureAvailBytes(''), null, '空串不是合法目录'); assert.equal(measureAvailBytes(undefined), null, '不传也要能兜住');