Publish curated Unraid-AppOps-Gateway source from 84f2a9958b2bdf1c1c13553925026d75f32703c3

This commit is contained in:
Public Source Publisher committed 2026-10-07 05:27:40 +00:00
1 parent 8dd4b40252
commit 5d598db0df
14 files changed
+2765 -46

No files matched your search

@@ -0,0 +1,397 @@
from __future__ import annotations
import asyncio
import json
import sys
from types import SimpleNamespace
import pytest
from mcp import Client
from test_hub_component_transport import call
from test_hub_component_transport import controller as _controller_fixture
from backend.app import mcp_server
from backend.app.services.deployment_broker import DeploymentBrokerClient
REPOSITORY = "jens/registered-app"
REQUEST_ID = "11111111-1111-4111-8111-111111111111"
PREFIX = "/v1/appops/registered-legacy/"
CAS = {
"expectedSourceFingerprint": "a" * 64,
"expectedRuntimeFingerprint": "b" * 64,
"expectedStateSha256": "c" * 64,
"expectedContainerIds": {"registered-app": "d" * 64},
}
@pytest.fixture
def controller(monkeypatch):
return _controller_fixture.__wrapped__(monkeypatch)
@pytest.fixture
def broker_calls(monkeypatch):
calls = []
monkeypatch.setattr(
DeploymentBrokerClient,
"_request",
lambda _self, method, path, **kwargs: calls.append((method, path, kwargs))
or {"status": "observed"},
)
return calls
def test_observe_client_accepts_only_repository_and_exact_route(broker_calls):
result = DeploymentBrokerClient().registered_legacy_operation(
"observe", {"repository": REPOSITORY}
)
assert result == {"status": "observed"}
assert broker_calls[0][0:2] == ("POST", PREFIX + "observe")
assert broker_calls[0][2]["payload"] == {"repository": REPOSITORY}
with pytest.raises(ValueError):
DeploymentBrokerClient().registered_legacy_operation(
"observe", {"repository": REPOSITORY, "environment": {"secret": "value"}}
)
assert len(broker_calls) == 1
def test_baseline_default_mcp_preserves_original_payload(broker_calls):
mcp_server.appops_registered_legacy_baseline(REPOSITORY, REQUEST_ID)
assert broker_calls[0][2]["payload"] == {
"repository": REPOSITORY,
"requestId": REQUEST_ID,
}
def test_baseline_capture_mcp_forwards_exact_optin_bindings(broker_calls):
mcp_server.appops_registered_legacy_baseline(
REPOSITORY,
REQUEST_ID,
capture_runtime_environment=True,
expected_source_fingerprint=CAS["expectedSourceFingerprint"],
expected_runtime_fingerprint=CAS["expectedRuntimeFingerprint"],
expected_state_sha256=CAS["expectedStateSha256"],
expected_container_ids=CAS["expectedContainerIds"],
)
assert broker_calls[0][2]["payload"] == {
"repository": REPOSITORY,
"requestId": REQUEST_ID,
"captureRuntimeEnvironment": True,
**CAS,
}
@pytest.mark.parametrize(
"capture,bindings", [(False, CAS), (True, {}), (1, CAS), ("true", CAS)]
)
def test_capture_contract_rejects_before_broker(capture, bindings, broker_calls):
with pytest.raises(ValueError):
mcp_server.appops_registered_legacy_baseline(
REPOSITORY,
REQUEST_ID,
capture_runtime_environment=capture,
expected_source_fingerprint=bindings.get("expectedSourceFingerprint"),
expected_runtime_fingerprint=bindings.get("expectedRuntimeFingerprint"),
expected_state_sha256=bindings.get("expectedStateSha256"),
expected_container_ids=bindings.get("expectedContainerIds"),
)
assert not broker_calls
def test_observe_http_has_no_request_id_or_mutating_helpers(controller, monkeypatch):
module, _projects = controller
calls = []
def observe(payload, **kwargs):
calls.append((payload, kwargs))
return {
"status": "observed",
"repository": REPOSITORY,
"sourceFingerprint": CAS["expectedSourceFingerprint"],
"runtimeFingerprint": CAS["expectedRuntimeFingerprint"],
"expectedStateSha256": CAS["expectedStateSha256"],
"containerIDs": CAS["expectedContainerIds"],
"imageIDs": {"registered-app": "sha256:" + "e" * 64},
"environmentMismatchKeys": ["registered-app/SERVER_URL"],
}
fake = SimpleNamespace(
observe=observe,
read_registered_state=lambda *_args: ({}, None),
RegisteredLegacyAdoptionError=ValueError,
)
monkeypatch.setitem(sys.modules, "registered_legacy_adoption", fake)
monkeypatch.setattr(
module,
"_registered_legacy_api_reader",
lambda *_args: pytest.fail("observe must not read Git API"),
)
code, result = call(
module,
PREFIX + "observe",
{"repository": REPOSITORY},
"_handle_registered_legacy",
)
assert code == 200 and result["status"] == "observed"
assert calls[0][0] == {"repository": REPOSITORY}
assert "environment" not in result
assert result["environmentMismatchKeys"] == ["registered-app/SERVER_URL"]
assert (
call(
module,
PREFIX + "observe",
{"repository": REPOSITORY, "requestId": REQUEST_ID},
"_handle_registered_legacy",
)[0]
== 400
)
def test_observe_mcp_schema_is_readonly_and_calls_no_other_operation(broker_calls):
async def exercise():
async with Client(mcp_server.appops_mcp) as client:
listing = await client.list_tools()
tool = next(
item
for item in listing.tools
if item.name == "appops.registered_legacy.observe"
)
assert tool.annotations.read_only_hint is True
assert tool.annotations.destructive_hint is False
assert set(tool.input_schema["properties"]) == {"repository"}
result = await client.call_tool(tool.name, {"repository": REPOSITORY})
assert not result.is_error
asyncio.run(exercise())
assert len(broker_calls) == 1
assert broker_calls[0][2]["payload"] == {"repository": REPOSITORY}
@pytest.mark.parametrize(
"changes",
[
{"captureRuntimeEnvironment": "true", **CAS},
{"captureRuntimeEnvironment": 1, **CAS},
{"captureRuntimeEnvironment": False, **CAS},
{"captureRuntimeEnvironment": True},
{"captureRuntimeEnvironment": True, **CAS, "expectedSourceFingerprint": "bad"},
{"captureRuntimeEnvironment": True, **CAS, "expectedContainerIds": {}},
{"environment": {"PRIVATE_KEY": "caller-value-must-not-escape"}},
],
)
def test_broker_baseline_rejects_incomplete_or_untyped_capture_before_transport(
changes, broker_calls
):
with pytest.raises(ValueError) as error:
DeploymentBrokerClient().registered_legacy_operation(
"baseline", {"repository": REPOSITORY, "requestId": REQUEST_ID, **changes}
)
assert "caller-value-must-not-escape" not in str(error.value)
assert not broker_calls
@pytest.mark.parametrize(
"changes",
[
{"captureRuntimeEnvironment": "true", **CAS},
{"captureRuntimeEnvironment": 1, **CAS},
{"captureRuntimeEnvironment": False, **CAS},
{"captureRuntimeEnvironment": True},
{
"captureRuntimeEnvironment": True,
**CAS,
"environment": {"PRIVATE_KEY": "caller-value-must-not-escape"},
},
],
)
def test_http_capture_shape_rejects_before_registry_or_core(
changes, controller, monkeypatch
):
module, _ = controller
monkeypatch.setattr(
module,
"_load_projects",
lambda: pytest.fail("invalid capture must not reach core"),
)
code, result = call(
module,
PREFIX + "baseline",
{"repository": REPOSITORY, "requestId": REQUEST_ID, **changes},
"_handle_registered_legacy",
)
assert code == 400 and result == {"status": "invalid_contract"}
assert "caller-value-must-not-escape" not in json.dumps(result)
def test_http_observation_extra_environment_is_rejected_without_value_echo(
controller, monkeypatch
):
module, _ = controller
fake = SimpleNamespace(
observe=lambda *_args, **_kwargs: {
"status": "observed",
"environment": {"PRIVATE_KEY": "private-observer-value"},
},
read_registered_state=lambda *_args: ({}, None),
RegisteredLegacyAdoptionError=type("AdoptionError", (RuntimeError,), {}),
)
monkeypatch.setitem(sys.modules, "registered_legacy_adoption", fake)
code, result = call(
module,
PREFIX + "observe",
{"repository": REPOSITORY},
"_handle_registered_legacy",
)
assert code == 503 and result == {"status": "registered_controller_unavailable"}
assert "private-observer-value" not in json.dumps(result)
def test_observe_requires_existing_signed_controller_authentication(
controller, monkeypatch
):
module, _ = controller
monkeypatch.setattr(
module, "_self_upgrade_signature_is_valid", lambda *_args, **_kwargs: False
)
monkeypatch.setattr(
module,
"_load_projects",
lambda: pytest.fail("unauthenticated observe must not read registry"),
)
assert (
call(
module,
PREFIX + "observe",
{"repository": REPOSITORY},
"_handle_registered_legacy",
)[0]
== 403
)
def test_mcp_wire_capture_boolean_does_not_coerce_strings_or_numbers(broker_calls):
async def exercise():
async with Client(mcp_server.appops_mcp) as client:
listing = await client.list_tools()
tool = next(
item
for item in listing.tools
if item.name == "appops.registered_legacy.baseline"
)
assert tool.annotations.read_only_hint is True
assert (
tool.input_schema["properties"]["capture_runtime_environment"][
"default"
]
is False
)
for value in ("true", 1):
result = await client.call_tool(
tool.name,
{
"repository": REPOSITORY,
"request_id": REQUEST_ID,
"capture_runtime_environment": value,
},
)
assert result.is_error
asyncio.run(exercise())
assert not broker_calls
def test_http_observe_real_registered_runtime_returns_only_safe_keynames(
controller, monkeypatch, tmp_path
):
from contextlib import nullcontext
from functools import partial
from test_registered_legacy_runtime import (
_load_module,
production_runtime as runtime_fixture,
)
core = _load_module()
runtime, boundary, project, model = runtime_fixture.__wrapped__(
core, monkeypatch, tmp_path
)
repository = "jens/quiz-monitor"
model["services"]["quiz-server"]["environment"]["KNOWLEDGE_OPTIMIZER_MODEL"] = (
"intended-test-model"
)
boundary.live["Config"]["Env"].append(
"KNOWLEDGE_OPTIMIZER_MODEL=observed-test-model"
)
monkeypatch.setattr(core, "_global_deploy_lock", lambda: nullcontext())
# Reuse the adapter fixture's validated registration against its temporary source tree.
monkeypatch.setattr(
core,
"validate_registered_legacy_target",
lambda repo, target: target["slug"]
if repo == repository
else pytest.fail("wrong registered target"),
)
monkeypatch.setattr(
core, "read_registered_state", lambda *_args, **_kwargs: ({}, None)
)
monkeypatch.setattr(
core,
"observe",
partial(core.observe, runtime=runtime, state_root=tmp_path / "state"),
)
monkeypatch.setitem(sys.modules, "registered_legacy_adoption", core)
module, _projects = controller
monkeypatch.setattr(module, "_load_projects", lambda: {repository: project})
code, result = call(
module,
PREFIX + "observe",
{"repository": repository},
"_handle_registered_legacy",
)
assert code == 200 and result["status"] == "observed"
assert result["environmentMismatchKeys"] == [
"quiz-server/KNOWLEDGE_OPTIMIZER_MODEL"
]
assert result["expectedStateSha256"] == core._state_digest(None)
assert set(result) == {
"status",
"repository",
"expectedStateSha256",
"sourceFingerprint",
"runtimeFingerprint",
"containerIDs",
"imageIDs",
"environmentMismatchKeys",
}
serialized = json.dumps(result)
assert "intended-test-model" not in serialized
assert "observed-test-model" not in serialized
assert "198.19.1.2" not in serialized
def test_http_complete_capture_forwards_no_environment_values(controller, monkeypatch):
module, _projects = controller
called = []
fake = SimpleNamespace(
baseline=lambda payload, **_kwargs: called.append(payload)
or {
"status": "baseline_captured",
"capturedEnvironmentKeys": ["service/SETTING"],
},
read_registered_state=lambda *_args: ({}, None),
RegisteredLegacyAdoptionError=ValueError,
)
monkeypatch.setitem(sys.modules, "registered_legacy_adoption", fake)
payload = {
"repository": REPOSITORY,
"requestId": REQUEST_ID,
"captureRuntimeEnvironment": True,
**CAS,
}
code, result = call(
module, PREFIX + "baseline", payload, "_handle_registered_legacy"
)
assert code == 200 and called == [payload]
assert result == {
"status": "baseline_captured",
"capturedEnvironmentKeys": ["service/SETTING"],
}