Naut-Peer/interop/make_fixture.py
ookami125 d8208685a2 Initial commit: multi-peer torrent download engine
Reactor/loop-pool engine with TCP/µTP/MSE transports, per-connection
pipelining, priority-driven piece selection with endgame, and the Python
FFI test harness.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:12:32 -04:00

76 lines
2.2 KiB
Python

from __future__ import annotations
import argparse
import hashlib
import os
import libtorrent as lt
from common import file_sha1, parse_size, write_manifest
def deterministic_bytes(offset: int, size: int) -> bytes:
out = bytearray()
counter = offset // 32
while len(out) < size:
out.extend(hashlib.sha256(f"torrent-peer-interop:{counter}".encode()).digest())
counter += 1
return bytes(out[:size])
def write_data(path: str, size: int) -> None:
with open(path, "wb") as f:
off = 0
while off < size:
n = min(1024 * 1024, size - off)
f.write(deterministic_bytes(off, n))
off += n
def make_torrent(root: str, size: int, piece_size: int) -> str:
os.makedirs(root, exist_ok=True)
data_path = os.path.join(root, "data.bin")
torrent_path = os.path.join(root, "test.torrent")
write_data(data_path, size)
fs = lt.file_storage()
lt.add_files(fs, data_path)
t = lt.create_torrent(fs, piece_size=piece_size)
t.set_priv(True)
t.add_tracker("http://fixture:9/announce")
lt.set_piece_hashes(t, root)
with open(torrent_path, "wb") as f:
f.write(lt.bencode(t.generate()))
return torrent_path
def main() -> int:
ap = argparse.ArgumentParser(description="Create the offline interop fixture.")
ap.add_argument("--out", required=True)
ap.add_argument("--size", default="32M")
ap.add_argument("--piece-size", default="256K")
args = ap.parse_args()
size = parse_size(args.size)
piece_size = parse_size(args.piece_size)
torrent_path = make_torrent(args.out, size, piece_size)
data_path = os.path.join(args.out, "data.bin")
ti = lt.torrent_info(torrent_path)
write_manifest(
os.path.join(args.out, "manifest.json"),
name=ti.name(),
size=size,
piece_size=piece_size,
num_pieces=ti.num_pieces(),
sha1=file_sha1(data_path),
announce="http://fixture:9/announce",
torrent=os.path.basename(torrent_path),
data=os.path.basename(data_path),
)
print(f"fixture ready: {size} bytes, {ti.num_pieces()} pieces", flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())