From e2ccdf0316243a1486109743e3de532cae5f3254 Mon Sep 17 00:00:00 2001 From: Paul Vinciguerra Date: Mon, 2 Dec 2019 13:40:33 -0500 Subject: [PATCH] papi: add a per-call _timeout option add the ability to override the default timeout value on a per-call basis. Use: rv = self.vapi.papi.cli_inband(cmd='wait 10', _timeout=15) Type: feature Change-Id: Ia90a58586a1f63e02118599a2a4b7141e5a0b90d Signed-off-by: Paul Vinciguerra --- src/vpp-api/python/vpp_papi/vpp_papi.py | 10 ++++++---- src/vpp-api/python/vpp_papi/vpp_transport_shmem.py | 6 ++++-- src/vpp-api/python/vpp_papi/vpp_transport_socket.py | 6 ++++-- test/test_cli.py | 7 ++++++- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/vpp-api/python/vpp_papi/vpp_papi.py b/src/vpp-api/python/vpp_papi/vpp_papi.py index 0ac86bbf307..e6eded85a63 100644 --- a/src/vpp-api/python/vpp_papi/vpp_papi.py +++ b/src/vpp-api/python/vpp_papi/vpp_papi.py @@ -620,6 +620,7 @@ class VPPApiClient(object): kwargs['_vl_msg_id'] = i no_type_conversion = kwargs.pop('_no_type_conversion', False) + timeout = kwargs.pop('_timeout', None) try: if self.transport.socket_index: @@ -645,7 +646,7 @@ class VPPApiClient(object): # Block until we get a reply. rl = [] while (True): - r = self.read_blocking(no_type_conversion) + r = self.read_blocking(no_type_conversion, timeout) if r is None: raise VPPIOError(2, 'VPP API client: read failed') msgname = type(r).__name__ @@ -699,10 +700,10 @@ class VPPApiClient(object): self.transport.write(b) return context - def read_blocking(self, no_type_conversion=False): + def read_blocking(self, no_type_conversion=False, timeout=None): """Get next received message from transport within timeout, decoded. - Note that noticifations have context zero + Note that notifications have context zero and are not put into receive queue (at least for socket transport), use async_thread with registered callback for processing them. @@ -720,8 +721,9 @@ class VPPApiClient(object): :type no_type_conversion: bool :returns: Decoded message, or None if no message (within timeout). :rtype: Whatever VPPType.unpack returns, depends on no_type_conversion. + :raises VppTransportShmemIOError if timed out. """ - msg = self.transport.read() + msg = self.transport.read(timeout=timeout) if not msg: return None return self.decode_incoming_msg(msg, no_type_conversion) diff --git a/src/vpp-api/python/vpp_papi/vpp_transport_shmem.py b/src/vpp-api/python/vpp_papi/vpp_transport_shmem.py index 4e40f2352e4..2563a6e89a8 100644 --- a/src/vpp-api/python/vpp_papi/vpp_transport_shmem.py +++ b/src/vpp-api/python/vpp_papi/vpp_transport_shmem.py @@ -116,12 +116,14 @@ class VppTransport(object): raise VppTransportShmemIOError(1, 'Not connected') return vpp_api.vac_write(bytes(buf), len(buf)) - def read(self): + def read(self, timeout=None): if not self.connected: raise VppTransportShmemIOError(1, 'Not connected') + if timeout is None: + timeout = self.read_timeout mem = ffi.new("char **") size = ffi.new("int *") - rv = vpp_api.vac_read(mem, size, self.read_timeout) + rv = vpp_api.vac_read(mem, size, timeout) if rv: strerror = 'vac_read failed. It is likely that VPP died.' raise VppTransportShmemIOError(rv, strerror) diff --git a/src/vpp-api/python/vpp_papi/vpp_transport_socket.py b/src/vpp-api/python/vpp_papi/vpp_transport_socket.py index c146c7b9386..d6431ca8c52 100644 --- a/src/vpp-api/python/vpp_papi/vpp_transport_socket.py +++ b/src/vpp-api/python/vpp_papi/vpp_transport_socket.py @@ -225,10 +225,12 @@ class VppTransport(object): return msg raise VppTransportSocketIOError(1, 'Unknown socket read error') - def read(self): + def read(self, timeout=None): if not self.connected: raise VppTransportSocketIOError(1, 'Not connected') + if timeout is None: + timeout = self.read_timeout try: - return self.q.get(True, self.read_timeout) + return self.q.get(True, timeout) except queue.Empty: return None diff --git a/test/test_cli.py b/test/test_cli.py index 7fa734b2231..a1ffbac81d8 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -17,7 +17,7 @@ class TestCLI(VppTestCase): @classmethod def setUpClass(cls): # using the framework default - # cls.vapi_response_timeout = 5 + cls.vapi_response_timeout = 5 super(TestCLI, cls).setUpClass() @classmethod @@ -44,6 +44,11 @@ class TestCLI(VppTestCase): vpp_transport_shmem.VppTransportShmemIOError) as ctx: rv = self.vapi.papi.cli_inband(cmd='wait 10') + def test_long_cli_delay_override(self): + """ Test per-command _timeout option.""" # noqa + rv = self.vapi.papi.cli_inband(cmd='wait 10', _timeout=15) + self.assertEqual(rv.retval, 0) + class TestCLIExtendedVapiTimeout(VppTestCase): maxDiff = None -- 2.16.6