mirror of
https://github.com/ClassicWasTaken/HaloCE-SteamFrame.git
synced 2026-10-15 22:00:28 +02:00
133 lines
6.5 KiB
Python
133 lines
6.5 KiB
Python
"""Large bundled helpers must survive SSH shell limits without remote temp files."""
|
|
import io
|
|
import shlex
|
|
import sys
|
|
import threading
|
|
import types
|
|
|
|
import pytest
|
|
|
|
from halo_frame_installer.install import Installer, run_remote_source
|
|
from halo_frame_installer.ssh import Settings, SSHError
|
|
from test_storage_host import RESOURCES, SD_ID, StorageConnection, maps_fixture
|
|
|
|
|
|
class PayloadConnection(StorageConnection):
|
|
def __init__(self, settings, **kwargs):
|
|
super().__init__(settings, **kwargs)
|
|
self.inline_calls = []
|
|
|
|
def run(self, argv, **kwargs):
|
|
if argv[1] == "-c":
|
|
payload = kwargs["input_data"]
|
|
assert isinstance(payload, bytes)
|
|
# Check the actual SSH shell command as well as Python's -c argument.
|
|
assert len(shlex.join(argv).encode("utf-8")) < 1024
|
|
assert len(argv[2].encode("utf-8")) < 512
|
|
assert self.settings.password not in shlex.join(argv)
|
|
self.inline_calls.append((argv, payload, kwargs))
|
|
else:
|
|
assert "input_data" not in kwargs
|
|
return super().run(argv, **kwargs)
|
|
|
|
|
|
@pytest.mark.parametrize("operation", ["install", "repair", "library", "uninstall", "storage"])
|
|
@pytest.mark.parametrize("storage_id", ["internal", SD_ID])
|
|
def test_every_helper_delivery_path_uses_bounded_commands_and_complete_payload(tmp_path, operation, storage_id):
|
|
settings = Settings("frame", "private", storage_id=storage_id,
|
|
reinstall_existing=operation == "repair")
|
|
connection = PayloadConnection(settings, existing=operation in ("repair", "library"))
|
|
installer = Installer(lambda _: connection, RESOURCES)
|
|
if operation in ("install", "repair"):
|
|
installer.run(settings, maps_fixture(tmp_path) if operation == "install" else None)
|
|
elif operation == "library":
|
|
installer.add_to_steam(settings)
|
|
elif operation == "uninstall":
|
|
installer.uninstall(settings)
|
|
else:
|
|
installer.discover_storage(settings)
|
|
assert connection.closed and connection.inline_calls
|
|
assert all(isinstance(options["cancel_event"], threading.Event)
|
|
and options["timeout"] == 90 for _, _, options in connection.inline_calls)
|
|
if operation == "storage":
|
|
assert connection.inline_calls[0][1] == (RESOURCES / "frame_storage.py").read_text(encoding="utf-8").encode()
|
|
assert not connection.uploads
|
|
else:
|
|
source = installer.remote_source()
|
|
# Reproduce the original per-string Linux failure with today's real resource.
|
|
legacy_command = shlex.join(["python3", "-c", source, "preflight"])
|
|
assert len(legacy_command.encode("utf-8")) >= 131072
|
|
assert connection.inline_calls[0][1] == source.encode("utf-8")
|
|
expected = "preflight-library" if operation == "library" else "preflight-uninstall" if operation == "uninstall" else "preflight"
|
|
assert connection.inline_calls[0][0][3] == expected
|
|
if operation == "repair":
|
|
assert "--repair" in connection.inline_calls[0][0]
|
|
if storage_id != "internal":
|
|
assert len(connection.inline_calls) > 1
|
|
assert all(argv[-2:] == ["--storage-id", SD_ID] for argv, _, _ in connection.inline_calls)
|
|
assert all(b"resolve_storage" in payload for _, payload, _ in connection.inline_calls[1:])
|
|
|
|
|
|
def test_real_bundled_helper_executes_intact_from_stdin_and_keeps_arguments(monkeypatch):
|
|
source = Installer(resource_dir=RESOURCES).remote_source()
|
|
arguments = ["preflight", "--repair", "--adopt-existing", "--storage-id", SD_ID]
|
|
namespace = {"__name__": "remote_source_fixture"}
|
|
if sys.platform == "win32":
|
|
monkeypatch.setitem(sys.modules, "pwd", types.SimpleNamespace())
|
|
monkeypatch.setitem(sys.modules, "frame_storage", types.ModuleType("prior_storage_fixture"))
|
|
|
|
class ExecuteConnection:
|
|
def run(self, argv, **kwargs):
|
|
monkeypatch.setattr(sys, "argv", ["-c", *argv[3:]])
|
|
monkeypatch.setattr(sys, "stdin", types.SimpleNamespace(buffer=io.BytesIO(kwargs["input_data"])))
|
|
exec(compile(argv[2], "<short SSH bootstrap>", "exec"), namespace)
|
|
return "loaded"
|
|
|
|
assert run_remote_source(ExecuteConnection(), source, arguments) == "loaded"
|
|
assert sys.argv == ["-c", *arguments]
|
|
assert namespace["SOURCE_COMMIT"] == "2ae0ee4e3e8a4dfdadfd528a5b085ca699fc9ea4"
|
|
assert all(callable(namespace[name]) for name in ("preflight", "preflight_uninstall", "preflight_library", "main"))
|
|
assert callable(namespace["storage_module"]().resolve_storage)
|
|
assert namespace["_hfi_source"] == source.encode("utf-8")
|
|
|
|
|
|
@pytest.mark.parametrize("alteration", ["truncated-valid-python", "different-same-length", "extra-bytes"])
|
|
def test_helper_integrity_check_rejects_changed_or_truncated_source_before_execution(monkeypatch, alteration):
|
|
source = "executed=True\n" + "# source padding\n" * 20000
|
|
namespace = {"__name__": "integrity_fixture"}
|
|
|
|
class TamperedConnection:
|
|
def run(self, argv, **kwargs):
|
|
payload = kwargs["input_data"]
|
|
if alteration == "truncated-valid-python":
|
|
payload = b"executed=True\n"
|
|
elif alteration == "different-same-length":
|
|
payload = payload.replace(b"executed=True", b"executed=None", 1)
|
|
else:
|
|
payload += b"# excess input\n"
|
|
monkeypatch.setattr(sys, "stdin", types.SimpleNamespace(buffer=io.BytesIO(payload)))
|
|
exec(compile(argv[2], "<short SSH bootstrap>", "exec"), namespace)
|
|
|
|
with pytest.raises(SystemExit, match="HFI_ERROR Setup helper transfer was incomplete"):
|
|
run_remote_source(TamperedConnection(), source)
|
|
assert "executed" not in namespace
|
|
|
|
|
|
@pytest.mark.parametrize("operation", ["install", "repair", "uninstall"])
|
|
def test_incomplete_preflight_transfer_stops_before_upload_or_mutation(tmp_path, operation):
|
|
settings = Settings("frame", "private", reinstall_existing=operation == "repair")
|
|
connection = PayloadConnection(settings, existing=operation == "repair")
|
|
|
|
def broken_transfer(argv, **kwargs):
|
|
assert argv[1] == "-c" and len(kwargs["input_data"]) > 131072
|
|
raise SSHError("Setup helper transfer was incomplete. Reconnect and retry.")
|
|
|
|
connection.run = broken_transfer
|
|
installer = Installer(lambda _: connection, RESOURCES)
|
|
with pytest.raises(SSHError, match="transfer was incomplete"):
|
|
if operation == "uninstall":
|
|
installer.uninstall(settings)
|
|
else:
|
|
installer.run(settings, maps_fixture(tmp_path) if operation == "install" else None)
|
|
assert connection.closed and not connection.uploads
|