import functools import http.server import logging import os import pathlib import subprocess import sys import tempfile import threading from typing import Any from typing import cast from typing import TYPE_CHECKING import unittest import libtorrent as lt from . import tdummy if TYPE_CHECKING: from libtorrent import _Entry class Handler(http.server.BaseHTTPRequestHandler): def __init__(self, *args: Any, serve_data: bytes, **kwargs: Any) -> None: self.serve_data = serve_data super().__init__(*args, **kwargs) def do_GET(self) -> None: logging.info("%s", self.requestline) self.send_response(200) self.send_header("content-length", str(len(self.serve_data))) self.end_headers() self.wfile.write(self.serve_data) class TestSimpleClient(unittest.TestCase): def setUp(self) -> None: # path relative to this file self.script_path = pathlib.Path(__file__).parent / ".." / "simple_client.py" self.tempdir = tempfile.TemporaryDirectory() self.tempdir_path = pathlib.Path(self.tempdir.name) self.torrent = tdummy.get_default() # set up a web seed to serve dummy torrent data self.server = http.server.HTTPServer( ("127.0.0.1", 0), functools.partial(Handler, serve_data=self.torrent.data) ) addr = self.server.server_address[0] port = self.server.server_address[1] self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.start() # construct a .torrent to point to our web seed tdict = self.torrent.dict tdict[b"url-list"] = b"".join( [b"http://", str(addr).encode(), b":", str(port).encode()] ) self.tdict = cast("_Entry", tdict) self.torrent_path = self.tempdir_path / "dummy.torrent" self.torrent_path.write_bytes(lt.bencode(self.tdict)) def tearDown(self) -> None: self.server.shutdown() self.server.server_close() self.tempdir.cleanup() def test_download_from_web_seed(self) -> None: proc = subprocess.run( [sys.executable, str(self.script_path), str(self.torrent_path)], cwd=self.tempdir_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, universal_newlines=True, timeout=20, ) self.assertEqual(proc.stderr, "") file_path = self.tempdir_path / os.fsdecode(self.torrent.files[0].path) self.assertEqual(file_path.read_bytes(), self.torrent.data)