Files
core/test/ecosystem-release/arm64/simulate.py
T

89 lines
3.4 KiB
Python

"""用显式准备的私有 ARM 内核运行独立应用,不改主机服务或沙箱策略。"""
from pathlib import Path
import json
import shutil
import subprocess
import time
SOURCE = Path(__file__).resolve().parent
ROOT = SOURCE.parents[2] / "target/arm64-cross"
def prepare_images():
init = ROOT / "initramfs"
for source, destination in [
("init.sh", init / "init-arm"),
("bootstrap.sh", init / "init-stage"),
("guest.sh", ROOT / "guest/run.sh"),
]:
shutil.copyfile(SOURCE / source, destination)
destination.chmod(0o755)
archive = ROOT / "guest-initramfs.gz"
with archive.open("wb") as output:
with subprocess.Popen(
["/usr/bin/find", ".", "-print0"], cwd=init, stdout=subprocess.PIPE
) as find:
try:
with subprocess.Popen(
["/usr/bin/cpio", "--null", "-o", "--format=newc", "--quiet"],
cwd=init, stdin=find.stdout, stdout=subprocess.PIPE,
) as cpio:
find.stdout.close()
try:
subprocess.run(["/usr/bin/gzip", "-1"], stdin=cpio.stdout, stdout=output, check=True)
finally:
cpio.stdout.close()
finally:
find.stdout.close()
if find.returncode or cpio.returncode:
raise RuntimeError("initramfs creation failed")
disk = ROOT / "guest.ext4"
with disk.open("wb") as output:
output.truncate(1024 * 1024 * 1024)
subprocess.run(
["/usr/sbin/mke2fs", "-q", "-t", "ext4", "-F", "-d", str(ROOT / "guest"), str(disk)],
check=True,
)
return archive, disk
def main():
archive, disk = prepare_images()
command = [
"/lib64/ld-linux-x86-64.so.2", "--library-path",
str(ROOT / "tools/usr/lib/x86_64-linux-gnu"),
str(ROOT / "tools/usr/bin/qemu-system-aarch64"),
"-machine", "virt", "-cpu", "cortex-a72", "-smp", "2", "-m", "768",
"-nographic", "-no-reboot", "-nic", "none",
"-kernel", str(ROOT / "iso/boot/vmlinuz-virt"), "-initrd", str(archive),
"-append", "console=ttyAMA0 rdinit=/init-arm panic=-1",
"-drive", f"file={disk},format=raw,if=none,readonly=on,id=payload",
"-device", "virtio-blk-device,drive=payload",
]
log = ROOT / "logs" / f"guest-{time.time_ns()}.log"
started = time.monotonic()
timed_out = False
with log.open("xb") as output:
try:
result = subprocess.run(command, stdout=output, stderr=subprocess.STDOUT, timeout=600)
exit_code = result.returncode
except subprocess.TimeoutExpired:
timed_out = True
exit_code = None
transcript = log.read_text(errors="replace")
required = ["DEVER_ARM_GUEST_EXIT=0", "ARM_HTTP_PASS"]
required.extend(f"ARM_WORKER_PASS={ecosystem}" for ecosystem in ("pip", "npm", "go"))
passed = exit_code == 0 and all(marker in transcript for marker in required)
record = {
"command": command, "exit_code": exit_code, "timed_out": timed_out, "passed": passed,
"seconds": time.monotonic() - started, "log": str(log),
}
log.with_suffix(".json").write_text(json.dumps(record, indent=2) + "\n")
print(json.dumps(record), flush=True)
if not passed:
raise RuntimeError("ARM guest acceptance failed; see serial log")
if __name__ == "__main__":
main()