runtime: handle GRC servers without XML-RPC introspection
GRC's SimpleXMLRPCServer uses register_instance() which doesn't expose system.listMethods. Wrap the connectivity check in a try/except so a Fault is treated as "connected" while ConnectionRefusedError still propagates.
This commit is contained in:
parent
b6a031acc2
commit
c793208932
@ -235,7 +235,9 @@ class ThriftMiddleware:
|
||||
units=prop.units if hasattr(prop, "units") else None,
|
||||
min_value=prop.min.value if prop.min else None,
|
||||
max_value=prop.max.value if prop.max else None,
|
||||
default_value=prop.defaultvalue.value if prop.defaultvalue else None,
|
||||
default_value=(
|
||||
prop.defaultvalue.value if prop.defaultvalue else None
|
||||
),
|
||||
knob_type=knob_type,
|
||||
)
|
||||
)
|
||||
@ -287,9 +289,7 @@ class ThriftMiddleware:
|
||||
avg_work_time_us=metrics.get("avg work time", 0.0),
|
||||
total_work_time_us=metrics.get("total work time", 0.0),
|
||||
avg_nproduced=metrics.get("avg nproduced", 0.0),
|
||||
input_buffer_pct=self._to_list(
|
||||
metrics.get("avg input % full", [])
|
||||
),
|
||||
input_buffer_pct=self._to_list(metrics.get("avg input % full", [])),
|
||||
output_buffer_pct=self._to_list(
|
||||
metrics.get("avg output % full", [])
|
||||
),
|
||||
|
||||
@ -31,8 +31,16 @@ class XmlRpcMiddleware:
|
||||
transport = xmlrpc.client.Transport()
|
||||
transport.timeout = XMLRPC_TIMEOUT
|
||||
proxy = xmlrpc.client.ServerProxy(url, transport=transport)
|
||||
# Verify connectivity
|
||||
proxy.system.listMethods()
|
||||
# Verify connectivity — GRC's SimpleXMLRPCServer uses
|
||||
# register_instance() which doesn't enable system.listMethods.
|
||||
# A Fault means the server responded (connected); only network
|
||||
# errors like ConnectionRefused indicate no server.
|
||||
try:
|
||||
proxy.system.listMethods()
|
||||
except ConnectionRefusedError:
|
||||
raise # actual connectivity failure — propagate
|
||||
except Exception as e:
|
||||
logger.debug("Introspection unavailable (normal for GRC servers): %s", e)
|
||||
logger.info("Connected to XML-RPC at %s", url)
|
||||
return cls(proxy, url)
|
||||
|
||||
|
||||
@ -125,7 +125,9 @@ class TestThriftMiddlewareVariables:
|
||||
"""list_variables excludes performance counter knobs."""
|
||||
mock_client.getKnobs.return_value = {
|
||||
"sig_source0::frequency": MockKnob("sig_source0::frequency", 1e6, 5),
|
||||
"null_sink0::avg throughput": MockKnob("null_sink0::avg throughput", 1e9, 5),
|
||||
"null_sink0::avg throughput": MockKnob(
|
||||
"null_sink0::avg throughput", 1e9, 5
|
||||
),
|
||||
}
|
||||
|
||||
variables = thrift_middleware.list_variables()
|
||||
|
||||
@ -53,6 +53,21 @@ class TestConnect:
|
||||
with pytest.raises(ConnectionRefusedError):
|
||||
XmlRpcMiddleware.connect("http://localhost:8080")
|
||||
|
||||
def test_connect_without_introspection(self):
|
||||
"""GRC servers don't enable system.listMethods — connect should still succeed."""
|
||||
from xmlrpc.client import Fault
|
||||
|
||||
with patch("gnuradio_mcp.middlewares.xmlrpc.xmlrpc.client") as mock_xmlrpc:
|
||||
mock_proxy = MagicMock()
|
||||
mock_proxy.system.listMethods.side_effect = Fault(
|
||||
1, "method 'system.listMethods' is not supported"
|
||||
)
|
||||
mock_xmlrpc.ServerProxy.return_value = mock_proxy
|
||||
mock_xmlrpc.Transport.return_value = MagicMock()
|
||||
|
||||
mw = XmlRpcMiddleware.connect("http://localhost:8080")
|
||||
assert mw is not None
|
||||
|
||||
|
||||
class TestConnectionInfo:
|
||||
def test_get_connection_info(self, xmlrpc_mw, mock_proxy):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user