test(guard): закрепить создание каталога как запись под read-only guard
ensureDir — такой же примитив записи lib/fs, как writeText и writeTextAtomic, и guard обязан покрывать его наравне с ними. /var/lib/hy2xs, созданный до успешной PHASE 0, уже делает хост изменённым: следующая чистая установка опознает его содержимое как чужую установку. Покрытие guard'ом всех примитивов ФС собрано в одном файле: непокрытый примитив — это дыра в границе PHASE 0, и заметить её можно только там, где проверяется весь набор.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { afterEach, describe, expect, test } from "bun:test";
|
import { afterEach, describe, expect, test } from "bun:test";
|
||||||
import { classifyFailure } from "../src/commands/install";
|
import { classifyFailure } from "../src/commands/install";
|
||||||
import { disableReadOnlyGuard, enableReadOnlyGuard, isReadOnlyGuardActive } from "../src/lib/guard";
|
import { disableReadOnlyGuard, enableReadOnlyGuard, isReadOnlyGuardActive } from "../src/lib/guard";
|
||||||
import { writeText, writeTextAtomic } from "../src/lib/fs";
|
import { ensureDir, writeText, writeTextAtomic } from "../src/lib/fs";
|
||||||
import {
|
import {
|
||||||
runMutating,
|
runMutating,
|
||||||
runMutatingHidden,
|
runMutatingHidden,
|
||||||
@@ -40,6 +40,9 @@ describe("read-only guard (PHASE 0)", () => {
|
|||||||
expect(isReadOnlyGuardActive()).toBe(false);
|
expect(isReadOnlyGuardActive()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Guard обязан покрывать ВСЕ примитивы записи lib/fs, а не только те, что
|
||||||
|
// существовали на момент его появления: непокрытый примитив — это дыра в
|
||||||
|
// границе PHASE 0, и заметить её можно только здесь.
|
||||||
test("под guard'ом запись в файл невозможна", async () => {
|
test("под guard'ом запись в файл невозможна", async () => {
|
||||||
enableReadOnlyGuard("test phase");
|
enableReadOnlyGuard("test phase");
|
||||||
await expect(writeText("/tmp/hy2xs-guard-probe", "x")).rejects.toThrow(/read-only guard violation/);
|
await expect(writeText("/tmp/hy2xs-guard-probe", "x")).rejects.toThrow(/read-only guard violation/);
|
||||||
@@ -48,6 +51,16 @@ describe("read-only guard (PHASE 0)", () => {
|
|||||||
).rejects.toThrow(/read-only guard violation/);
|
).rejects.toThrow(/read-only guard violation/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Создание каталога — тоже запись. /var/lib/hy2xs, созданный до успешной
|
||||||
|
// PHASE 0, уже делает хост изменённым: следующая чистая установка опознает
|
||||||
|
// его содержимое как чужую установку.
|
||||||
|
test("под guard'ом создание каталога невозможно", async () => {
|
||||||
|
enableReadOnlyGuard("test phase");
|
||||||
|
await expect(ensureDir("/tmp/hy2xs-guard-probe-dir", { mode: 0o755 })).rejects.toThrow(
|
||||||
|
/read-only guard violation/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("под guard'ом мутирующие раннеры недоступны", async () => {
|
test("под guard'ом мутирующие раннеры недоступны", async () => {
|
||||||
enableReadOnlyGuard("test phase");
|
enableReadOnlyGuard("test phase");
|
||||||
await expect(runMutating`true`).rejects.toThrow(/read-only guard violation/);
|
await expect(runMutating`true`).rejects.toThrow(/read-only guard violation/);
|
||||||
|
|||||||
Reference in New Issue
Block a user