Files
MeshChatX/tests/backend/test_repository_server_manager.py
T

211 lines
7.2 KiB
Python

# SPDX-License-Identifier: 0BSD
import time
import urllib.request
from subprocess import CompletedProcess
from unittest.mock import patch
from meshchatx.src.backend.repository_server_manager import (
RepositoryServerManager,
build_repository_index_html,
bundled_pip_targets,
download_bundled_wheels_to_directory,
meshchat_bundle_project_root,
)
def test_bundled_pip_targets_includes_extra_from_env(monkeypatch):
monkeypatch.setenv("MESHCHAT_REPOSITORY_EXTRA_PIP", "foo, bar")
names = bundled_pip_targets()
assert "foo" in names
assert "bar" in names
assert "rns" in names
assert "rnspure" in names
def test_seed_copies_bundled_wheels_from_public(tmp_path):
identity = tmp_path / "identity"
identity.mkdir()
public = tmp_path / "public"
bundled_pub = public / "repository-server-bundled" / "bundled"
bundled_pub.mkdir(parents=True)
(bundled_pub / "from_build.whl").write_bytes(b"wheeldata")
mgr = RepositoryServerManager(str(identity), public_dir=str(public))
rows = mgr.list_entries()
bundled_names = [r["name"] for r in rows if r["source"] == "bundled"]
assert "from_build.whl" in bundled_names
def test_seed_skips_when_wheel_already_present(tmp_path):
identity = tmp_path / "identity"
identity.mkdir()
public = tmp_path / "public"
bundled_pub = public / "repository-server-bundled" / "bundled"
bundled_pub.mkdir(parents=True)
(bundled_pub / "same.whl").write_bytes(b"from_public")
dest = identity / "repository-server" / "bundled"
dest.mkdir(parents=True)
(dest / "same.whl").write_bytes(b"user_keeps")
RepositoryServerManager(str(identity), public_dir=str(public))
assert (dest / "same.whl").read_bytes() == b"user_keeps"
def test_meshchat_bundle_project_root_exists():
root = meshchat_bundle_project_root()
assert root is not None
assert (root / "pyproject.toml").is_file()
assert (root / "meshchatx").is_dir()
def test_build_repository_index_html_lists_files(tmp_path):
bundled = tmp_path / "bundled"
uploads = tmp_path / "uploads"
bundled.mkdir()
uploads.mkdir()
(bundled / "pkg.whl").write_bytes(b"x")
(uploads / "note.txt").write_bytes(b"ab")
html_out = build_repository_index_html(str(bundled), str(uploads))
assert "MeshChatX repository" in html_out
assert "pkg.whl" in html_out
assert "note.txt" in html_out
assert 'href="bundled/' in html_out
assert 'href="uploads/' in html_out
def test_save_list_delete_upload(tmp_path):
mgr = RepositoryServerManager(str(tmp_path))
ok, err = mgr.save_upload("test.whl", b"abc")
assert ok and err is None
rows = mgr.list_entries()
assert len(rows) == 1
assert rows[0]["name"] == "test.whl"
assert rows[0]["source"] == "upload"
ok2, err2 = mgr.delete_upload("test.whl")
assert ok2 and err2 is None
assert mgr.list_entries() == []
def test_save_rejects_bad_filename(tmp_path):
mgr = RepositoryServerManager(str(tmp_path))
ok, err = mgr.save_upload("../evil.whl", b"x")
assert not ok
@patch(
"meshchatx.src.backend.repository_server_manager.download_bundled_wheels_to_directory"
)
def test_refresh_invokes_bundled_downloader(mock_dl, tmp_path):
mock_dl.return_value = {"ok": True, "downloaded": ["rns"], "failed": {}}
mgr = RepositoryServerManager(str(tmp_path))
out = mgr.refresh_bundled_wheels()
assert out["ok"] is True
mock_dl.assert_called_once()
assert mock_dl.call_args.kwargs.get("pip") is None
@patch("meshchatx.src.backend.repository_server_manager._download_wheel_via_pypi_index")
@patch("meshchatx.src.backend.repository_server_manager.subprocess.run")
@patch("meshchatx.src.backend.repository_server_manager.shutil.which")
def test_download_bundled_wheels_to_directory(
mock_which, mock_run, mock_pypi, tmp_path, monkeypatch
):
monkeypatch.setenv("MESHCHAT_REPOSITORY_EXTRA_PIP", "")
mock_which.return_value = "/fake/pip3"
mock_pypi.return_value = (False, "offline")
def fake_run(cmd, **kwargs):
assert cmd[0] == "/fake/pip3"
assert cmd[1] in ("download", "wheel")
assert cmd[2] == "--no-deps"
assert cmd[3] in ("-d", "-w")
return CompletedProcess(cmd, 0, "", "")
mock_run.side_effect = fake_run
dest = tmp_path / "out"
out = download_bundled_wheels_to_directory(dest, "/fake/pip3")
assert out["ok"] is True
n = len(bundled_pip_targets())
assert mock_run.call_count == n
assert mock_pypi.call_count == n - 1
@patch("meshchatx.src.backend.repository_server_manager._download_wheel_via_pypi_index")
@patch("meshchatx.src.backend.repository_server_manager.subprocess.run")
@patch("meshchatx.src.backend.repository_server_manager.shutil.which")
def test_refresh_calls_pip_after_pypi_fails(
mock_which, mock_run, mock_pypi, tmp_path, monkeypatch
):
monkeypatch.setenv("MESHCHAT_REPOSITORY_EXTRA_PIP", "")
mock_which.return_value = "/fake/pip3"
mock_pypi.return_value = (False, "offline")
def fake_run(cmd, **kwargs):
assert cmd[0] == "/fake/pip3"
assert cmd[1] in ("download", "wheel")
assert cmd[2] == "--no-deps"
assert cmd[3] in ("-d", "-w")
return CompletedProcess(cmd, 0, "", "")
mock_run.side_effect = fake_run
mgr = RepositoryServerManager(str(tmp_path))
out = mgr.refresh_bundled_wheels()
assert out["ok"] is True
n = len(bundled_pip_targets())
assert mock_run.call_count == n
assert mock_pypi.call_count == n - 1
def test_http_start_stop_and_status(tmp_path):
mgr = RepositoryServerManager(str(tmp_path))
assert mgr.status()["http"]["running"] is False
first = mgr.start_http_server("127.0.0.1", 0)
assert first["ok"] is True
assert first["port"] > 0
time.sleep(0.05)
st = mgr.status()["http"]
assert st["running"] is True
assert st["url"] == f"http://127.0.0.1:{first['port']}/"
assert st["last_port"] == first["port"]
second = mgr.start_http_server("127.0.0.1", first["port"])
assert second["ok"] is False
assert second["error"] == "already_running"
mgr.stop_http_server()
assert mgr.status()["http"]["running"] is False
def test_http_invalid_host(tmp_path):
mgr = RepositoryServerManager(str(tmp_path))
out = mgr.start_http_server(" ", 8787)
assert out["ok"] is False
assert out["error"] == "invalid_host"
def test_http_get_root(tmp_path):
mgr = RepositoryServerManager(str(tmp_path))
mgr.save_upload("listed.whl", b"wheel")
out = mgr.start_http_server("127.0.0.1", 0)
assert out["ok"] is True
time.sleep(0.08)
url = out["url"]
try:
req = urllib.request.Request(url, method="GET")
with urllib.request.urlopen(req, timeout=5) as resp:
assert resp.status == 200
body = resp.read().decode("utf-8")
assert "listed.whl" in body
assert "uploads/" in body
finally:
mgr.stop_http_server()
def test_http_restart_uses_last_listen(tmp_path):
mgr = RepositoryServerManager(str(tmp_path))
a = mgr.start_http_server("127.0.0.1", 0)
assert a["ok"] is True
port = a["port"]
mgr.stop_http_server()
b = mgr.restart_http_server(None, None)
assert b["ok"] is True
assert b["port"] == port
mgr.stop_http_server()