papi: add a per-call _timeout option 40/23740/2
authorPaul Vinciguerra <pvinci@vinciconsulting.com>
Mon, 2 Dec 2019 18:40:33 +0000 (13:40 -0500)
committerOle Trøan <otroan@employees.org>
Tue, 3 Dec 2019 09:28:18 +0000 (09:28 +0000)
 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 <pvinci@vinciconsulting.com>
src/vpp-api/python/vpp_papi/vpp_papi.py
src/vpp-api/python/vpp_papi/vpp_transport_shmem.py
src/vpp-api/python/vpp_papi/vpp_transport_socket.py
test/test_cli.py

index 0ac86bb..e6eded8 100644 (file)
@@ -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)
index 4e40f23..2563a6e 100644 (file)
@@ -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)
index c146c7b..d6431ca 100644 (file)
@@ -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
index 7fa734b..a1ffbac 100644 (file)
@@ -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