emacs/test/lisp/jsonrpc-resources/common.py
João Távora 36036e71c0 Jsonrpc: migrate more tests to Python subprocess fixtures
All tests now use 'jsonrpc--with-python-fixture' with a Python3
subprocess instead of the in-Emacs TCP server.  Changed the "harakiri"
method to be a request instead of a notification for to reduce chance of
"Sentinel hasn't run" warning.

The two in-Emacs-RPC-specific error tests ('errors-with--32601' and
'signals-an--32603-JSONRPC-error') are dropped with the fixture itself,
as the error paths they exercise are internal to the Emacs Lisp
dispatcher and have no direct Python equivalent.  They will have to be
re-done later on in other form.

* test/lisp/jsonrpc-resources/server-emacsrpc.py: New file.

* test/lisp/jsonrpc-resources/server-anxious-nested.py: Use new
  harakiri.

* test/lisp/jsonrpc-resources/server-emacsrpc.py: Use new harakiri.

* test/lisp/jsonrpc-resources/server-harakiri.py: Use new harakiri.

* test/lisp/jsonrpc-resources/server-remote-during-sync-1.py: Use new
  harakiri.

* test/lisp/jsonrpc-resources/server-remote-during-sync-2.py: Use new
  harakiri.

* test/lisp/jsonrpc-resources/server-remote-error.py: Use new harakiri.

* test/lisp/jsonrpc-resources/common.py (harakiri): New definition.

* test/lisp/jsonrpc-tests.el
(jsonrpc--with-python-fixture): Rework, move up.
(jsonrpc-connection-ready-p): Move up.
(jsonrpc--call-with-emacsrpc-fixture)
(jsonrpc--with-emacsrpc-fixture)
(errors-with--32601)
(signals-an--32603-JSONRPC-error): Remove.
(returns-3, times-out, doesnt-time-out, stretching-it-but-works)
(deferred-action-toolate, deferred-action-intime)
(deferred-action-complex-tests): Migrate to Python fixture.
(scontrol-remote-during-sync-1, scontrol-remote-during-sync-2)
(scontrol-anxious-nested, scontrol-remote-error)
(shutdown-clean-after-notification): Tweak.
2026-05-17 19:28:07 +01:00

41 lines
1.3 KiB
Python

"""Common JSONRPC framing helpers for jsonrpc.el test servers."""
import json
import sys
def read_msg():
"""Read one Content-Length-framed JSON-RPC message from stdin."""
headers = {}
while True:
line = sys.stdin.buffer.readline()
if not line:
return None
text = line.decode('utf-8').rstrip('\r\n')
if not text:
break
if ':' in text:
k, _, v = text.partition(':')
headers[k.strip()] = v.strip()
n = int(headers.get('Content-Length', 0))
return json.loads(sys.stdin.buffer.read(n).decode('utf-8')) if n else None
def write_msg(msg):
"""Write one Content-Length-framed JSON-RPC message to stdout."""
body = json.dumps(msg, ensure_ascii=False).encode('utf-8')
sys.stdout.buffer.write(
f'Content-Length: {len(body)}\r\n\r\n'.encode('utf-8') + body
)
sys.stdout.buffer.flush()
def log(text):
"""Write a log line to stderr."""
print(f'[test-server] {text}', file=sys.stderr, flush=True)
def harakiri(msg):
"""Maybe handle harakiri request/notif in msg."""
if msg.get('method') == 'harakiri':
log('-> very clean harakiri')
if (mid := msg.get('id')) is not None:
write_msg({'jsonrpc': '2.0', 'id': mid, 'result': True})
return True
return False