mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-10-13 04:01:35 +00:00
102 lines
3.7 KiB
Python
102 lines
3.7 KiB
Python
"""Opt-in native plugin discovery regression, without model calls or hook execution.
|
|
|
|
Run with REME_CODEX_BIN=/path/to/codex pytest tests/integration/test_codex_plugin_install.py.
|
|
The selected runtime must support the hooks/list app-server API.
|
|
"""
|
|
|
|
# pylint: disable=missing-function-docstring
|
|
|
|
import json
|
|
import os
|
|
import queue
|
|
import subprocess
|
|
import threading
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
MARKETPLACE = Path(__file__).resolve().parents[2] / "integrations/codex"
|
|
EVENTS = {"sessionStart", "sessionEnd", "userPromptSubmit", "stop", "subagentStop"}
|
|
|
|
|
|
def test_installed_plugin_exposes_all_hooks_before_trust(tmp_path):
|
|
binary = os.environ.get("REME_CODEX_BIN")
|
|
if not binary:
|
|
pytest.skip("Set REME_CODEX_BIN to run the native Codex installation check")
|
|
home = tmp_path / "codex-home"
|
|
home.mkdir()
|
|
env = {**os.environ, "CODEX_HOME": str(home)}
|
|
for args in (
|
|
["plugin", "marketplace", "add", str(MARKETPLACE)],
|
|
["plugin", "add", "reme@reme-codex"],
|
|
):
|
|
result = subprocess.run([binary, *args], env=env, capture_output=True, text=True, check=False, timeout=60)
|
|
assert result.returncode == 0, result.stderr
|
|
|
|
with (
|
|
(tmp_path / "app-server.log").open("w", encoding="utf-8") as stderr,
|
|
subprocess.Popen(
|
|
[binary, "app-server"],
|
|
env=env,
|
|
cwd=tmp_path,
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE,
|
|
stderr=stderr,
|
|
text=True,
|
|
) as process,
|
|
):
|
|
responses = queue.Queue()
|
|
|
|
def receive():
|
|
for line in process.stdout:
|
|
responses.put(json.loads(line))
|
|
|
|
reader = threading.Thread(target=receive, daemon=True)
|
|
reader.start()
|
|
|
|
def request(request_id, method, params):
|
|
process.stdin.write(json.dumps({"id": request_id, "method": method, "params": params}) + "\n")
|
|
process.stdin.flush()
|
|
while True:
|
|
response = responses.get(timeout=30)
|
|
if response.get("id") == request_id:
|
|
assert "error" not in response, response
|
|
return response["result"]
|
|
|
|
try:
|
|
request(
|
|
0,
|
|
"initialize",
|
|
{
|
|
"clientInfo": {"name": "reme-install-test", "version": "1.0"},
|
|
"capabilities": {"experimentalApi": True},
|
|
},
|
|
)
|
|
process.stdin.write(json.dumps({"method": "initialized", "params": {}}) + "\n")
|
|
process.stdin.flush()
|
|
details = request(
|
|
1,
|
|
"plugin/read",
|
|
{"marketplacePath": str(MARKETPLACE / ".agents/plugins/marketplace.json"), "pluginName": "reme"},
|
|
)["plugin"]
|
|
assert details["summary"]["installed"] and details["summary"]["enabled"]
|
|
assert details["mcpServers"] == ["reme"]
|
|
assert {hook["eventName"] for hook in details["hooks"]} == EVENTS
|
|
|
|
entries = request(2, "hooks/list", {"cwds": [str(tmp_path)]})["data"]
|
|
assert len(entries) == 1
|
|
assert not entries[0]["errors"]
|
|
hooks = [hook for hook in entries[0]["hooks"] if hook.get("pluginId") == "reme@reme-codex"]
|
|
assert len(hooks) == 7
|
|
assert {hook["eventName"] for hook in hooks} == EVENTS
|
|
assert all(hook["enabled"] and hook["trustStatus"] == "untrusted" for hook in hooks)
|
|
finally:
|
|
process.stdin.close()
|
|
process.terminate()
|
|
try:
|
|
process.wait(timeout=10)
|
|
except subprocess.TimeoutExpired:
|
|
process.kill()
|
|
process.wait(timeout=10)
|
|
reader.join(timeout=5)
|
|
process.stdout.close()
|