This commit is contained in:
2026-08-18 09:20:44 +02:00
commit b826cd721a
522 changed files with 93730 additions and 0 deletions
+198
View File
@@ -0,0 +1,198 @@
#!/bin/sh
set -eu
: "${PRE15_DUT:?PRE15_DUT is required}"
: "${PRE15_ROOT:?PRE15_ROOT is required}"
: "${PRE15_RUN_DIR:?PRE15_RUN_DIR is required}"
: "${PRE15_LIB_DIR:?PRE15_LIB_DIR is required}"
. "$PRE15_LIB_DIR/runner.sh"
gate=$PRE15_DUT/tests/pre15/gates/P15-005.sh
tuple_oracle=$PRE15_DUT/tests/pre15/fixtures/B06-tuples.json
ownership_oracle=$PRE15_DUT/tests/pre15/fixtures/B06-ownership.json
artifacts=$PRE15_RUN_DIR/artifacts
for tool in cc python3 sha256sum; do
command -v "$tool" >/dev/null 2>&1 || \
pre15_infra_blocked "missing B06 host tool: $tool"
done
pre15_record_fixture b06-gate "$gate"
pre15_record_fixture b06-tuple-oracle "$tuple_oracle"
pre15_record_fixture b06-ownership-oracle "$ownership_oracle"
for source in internal.h data.c decompressor.c inode.c super.c xattr.c zdata.c zmap.c; do
pre15_record_fixture "b06-$source" "$PRE15_DUT/src/$source"
done
mkdir -p "$artifacts"
pre15_target_reached
if "$gate" --worktree --oracle "$tuple_oracle" \
--output "$artifacts/gate" >"$artifacts/gate.stdout" \
2>"$artifacts/gate.stderr"; then
:
else
pre15_dut_fail 'B06 G02 candidate replay failed'
fi
if python3 - "$PRE15_ROOT" "$ownership_oracle" "$artifacts/gate" \
"$artifacts/ownership-check.json" <<'PY'
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import re
import sys
root = Path(sys.argv[1])
expected = json.loads(Path(sys.argv[2]).read_text(encoding="ascii"))
gate_dir = Path(sys.argv[3])
output = Path(sys.argv[4])
result = json.loads((gate_dir / "result.json").read_text(encoding="ascii"))
ownership = json.loads((gate_dir / "ownership.json").read_text(encoding="ascii"))
if result["status"] != "GO" or result["tuple_status"] != "PASS":
raise SystemExit(f"candidate tuple result is not GO: {result!r}")
if not result["object_mode"] or result["oracle_equal"] is not True:
raise SystemExit(f"candidate did not replay the frozen object oracle: {result!r}")
if ownership["status"] != "PASS" or ownership["failures"]:
raise SystemExit(f"candidate ownership result failed: {ownership['failures']!r}")
if ownership["consumers"] != expected["consumers"]:
raise SystemExit("ownership consumer set changed")
if ownership["direct_metadata_functions"] != expected["direct_metadata_functions"]:
raise SystemExit("direct metadata consumer inventory changed")
if ownership["helper_paths"]["paths"] != expected["helper_paths"]:
raise SystemExit("actual helper lifecycle paths changed")
metric_order = expected["metric_order"]
actual_metrics = {
item["function"]: [item[field] for field in metric_order]
for item in ownership["candidate_contract"]["function_metrics"]
}
if actual_metrics != expected["function_metrics"]:
raise SystemExit("per-function ownership metrics changed")
def extract_function(source: str, name: str) -> str:
match = re.search(r"^" + re.escape(name) + r"\s*\(", source, re.MULTILINE)
if not match:
raise SystemExit(f"backend function missing: {name}")
start = source.rfind("\n\n", 0, match.start()) + 2
brace = source.find("{", match.end())
depth = 0
state = "code"
index = brace
while index < len(source):
char = source[index]
following = source[index + 1] if index + 1 < len(source) else ""
if state == "code":
if char == "/" and following == "*":
state = "block"
index += 2
continue
if char == "/" and following == "/":
state = "line"
index += 2
continue
if char == '"':
state = "string"
elif char == "'":
state = "character"
elif char == "{":
depth += 1
elif char == "}":
depth -= 1
if depth == 0:
return source[start : index + 1] + "\n"
elif state == "block" and char == "*" and following == "/":
state = "code"
index += 2
continue
elif state == "line" and char == "\n":
state = "code"
elif state in {"string", "character"}:
if char == "\\":
index += 2
continue
if (state == "string" and char == '"') or (
state == "character" and char == "'"
):
state = "code"
index += 1
raise SystemExit(f"unterminated backend function: {name}")
backend_hashes = {}
for key, frozen_hash in expected["freebsd_backend_function_sha256"].items():
filename, function = key.split(":", 1)
source = (root / "repo-pre-15" / "src" / filename).read_text(encoding="utf-8")
current_hash = hashlib.sha256(
extract_function(source, function).encode("utf-8")
).hexdigest()
backend_hashes[key] = current_hash
if current_hash != frozen_hash:
raise SystemExit(f"FreeBSD backend lifecycle changed: {key}")
internal_path = root / "repo-pre-15" / "src" / "internal.h"
internal = internal_path.read_text(encoding="utf-8")
match = re.search(
r"^struct erofs_map_blocks \{\n.*?^\};\n",
internal,
re.MULTILINE | re.DOTALL,
)
if not match:
raise SystemExit("missing legacy map tuple object")
map_hash = hashlib.sha256(match.group(0).encode("utf-8")).hexdigest()
if map_hash != expected["map_blocks_sha256"]:
raise SystemExit("B07 map objectization leaked into B06")
required = [
"struct erofs_buf {",
"#define EROFS_BUF_INITIALIZER { .data = NULL, .release = NULL }",
"void erofs_put_metabuf(struct erofs_buf *buf);",
"int erofs_bread(struct erofs_sb_info *sbi, erofs_off_t off, size_t len, void **bufp);",
"void erofs_brelse(void *buf);",
]
for marker in required:
if marker not in internal:
raise SystemExit(f"required B06/raw API marker missing: {marker}")
if re.search(
r"erofs_read_metadata\s*\([^;]*void\s*\*\*bufp\s*\)\s*;",
internal,
re.MULTILINE | re.DOTALL,
):
raise SystemExit("legacy metadata void-pointer API remains")
for filename in ("dir.c", "namei.c"):
text = (root / "repo-pre-15" / "src" / filename).read_text(encoding="utf-8")
if "struct erofs_buf" in text or "erofs_put_metabuf" in text:
raise SystemExit(f"raw directory consumer was objectized: {filename}")
summary = {
"status": "PASS",
"tuple_cases": result["case_count"],
"tuple_oracle_equal": result["oracle_equal"],
"ownership_paths": result["ownership_path_count"],
"helper_paths": len(expected["helper_paths"]),
"function_metrics": len(actual_metrics),
"freebsd_backend_functions": len(backend_hashes),
"map_blocks_sha256": map_hash,
"qemu": result["qemu"],
"full_feature_suite": result["full_feature_suite"],
}
with output.open("x", encoding="ascii") as stream:
json.dump(summary, stream, ensure_ascii=True, indent=2, sort_keys=True)
stream.write("\n")
print("B06 ownership PASS tuples=14 paths=22 helper=5 functions=28")
PY
then
:
else
pre15_dut_fail 'B06 ownership fixture comparison failed'
fi
sha256sum "$artifacts/gate/result.json" "$artifacts/gate/tuples.json" \
"$artifacts/gate/ownership.json" "$artifacts/ownership-check.json" \
>"$artifacts/SHA256SUMS"
printf 'B06 PASS explicit metadata ownership and frozen tuple replay\n'