8e389c03f8
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
61 lines
1.9 KiB
Python
Executable File
61 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Набор для отключения/возврата HDD во время F5."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pathlib
|
|
import sys
|
|
|
|
|
|
SIZE = 262_181
|
|
|
|
|
|
def data() -> bytes:
|
|
return bytes(((index * 41 + (index >> 9) * 7 + 0x35) & 0xFF)
|
|
for index in range(SIZE))
|
|
|
|
|
|
def create(root: pathlib.Path) -> None:
|
|
media = root / "MEDIA"
|
|
(media / "DEEP").mkdir(parents=True)
|
|
(media / "DATA.BIN").write_bytes(data())
|
|
(media / "DEEP" / "INNER.TXT").write_text(
|
|
"media-change fixture\n", encoding="ascii")
|
|
|
|
|
|
def verify(root: pathlib.Path) -> None:
|
|
failures: list[str] = []
|
|
source = root / "MEDIA" / "DATA.BIN"
|
|
target = root / "DATA.BIN"
|
|
|
|
if not source.is_file() or source.read_bytes() != data():
|
|
failures.append("исходный MEDIA/DATA.BIN повреждён")
|
|
if not target.is_file() or target.read_bytes() != data():
|
|
failures.append("DATA.BIN не скопирован после возврата HDD")
|
|
temporaries = sorted(root.glob("~SC*.TMP"))
|
|
if temporaries:
|
|
failures.append("после media-change остался временный файл")
|
|
inner = root / "MEDIA" / "DEEP" / "INNER.TXT"
|
|
if not inner.is_file() or inner.read_bytes() != b"media-change fixture\n":
|
|
failures.append("вложенный контрольный файл повреждён")
|
|
|
|
if failures:
|
|
for failure in failures:
|
|
print(f"FAIL: {failure}")
|
|
raise SystemExit(1)
|
|
print("PASS: HDD removal дал управляемый отказ; после возврата DATA совпал, temp нет.")
|
|
|
|
|
|
def main() -> None:
|
|
if len(sys.argv) != 3 or sys.argv[1] not in {"create", "verify"}:
|
|
raise SystemExit(f"usage: {sys.argv[0]} create|verify DIR")
|
|
root = pathlib.Path(sys.argv[2])
|
|
if sys.argv[1] == "create":
|
|
create(root)
|
|
else:
|
|
verify(root)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|