tests: handle removed interface

Catch exception if sw_if_index is invalid when querying interface
binding config. If the interface is not there, it's surely not bound to
any table ...

Type: improvement
Change-Id: I1f3e04a631653feb5c2350662b6a041adccefa1f
Signed-off-by: Klement Sekera <klement.sekera@gmail.com>
diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py
index b605948..f5e5a88 100644
--- a/test/vpp_ip_route.py
+++ b/test/vpp_ip_route.py
@@ -5,10 +5,10 @@
 """
 
 from vpp_object import VppObject
-from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
 from vpp_ip import DpoProto, INVALID_INDEX, VppIpAddressUnion, \
     VppIpMPrefix
 from ipaddress import ip_network, ip_address, IPv4Network, IPv6Network
+from vpp_papi_exceptions import UnexpectedApiReturnValueError
 
 # from vnet/vnet/mpls/mpls_types.h
 MPLS_IETF_MAX_LABEL = 0xfffff
@@ -340,9 +340,14 @@
     def query_vpp_config(self):
         if 0 == self.table.table_id:
             return False
-        return self._test.vapi.sw_interface_get_table(
-            self.intf.sw_if_index,
-            self.table.is_ip6).vrf_id == self.table.table_id
+        try:
+            return self._test.vapi.sw_interface_get_table(
+                self.intf.sw_if_index,
+                self.table.is_ip6).vrf_id == self.table.table_id
+        except UnexpectedApiReturnValueError as e:
+            if e.retval == -2:  # INVALID_SW_IF_INDEX
+                return False
+            raise
 
     def object_id(self):
         return "interface-bind-%s-%s" % (self.intf, self.table)
diff --git a/test/vpp_papi_exceptions.py b/test/vpp_papi_exceptions.py
new file mode 100644
index 0000000..2f7da96
--- /dev/null
+++ b/test/vpp_papi_exceptions.py
@@ -0,0 +1,15 @@
+class CliFailedCommandError(Exception):
+    """ cli command failed."""
+
+
+class CliSyntaxError(Exception):
+    """ cli command had a syntax error."""
+
+
+class UnexpectedApiReturnValueError(Exception):
+    """ exception raised when the API return value is unexpected """
+
+    def __init__(self, retval, message):
+        self.retval = retval
+        self.message = message
+        super().__init__(message)
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index c0e88f8..9ff616c 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -7,13 +7,13 @@
 
 import os
 import time
-from collections import deque
 import queue
 from six import moves, iteritems
 from config import config
-from vpp_papi import VPPApiClient, mac_pton
+from vpp_papi import VPPApiClient
 from hook import Hook
-from vpp_ip_route import MPLS_IETF_MAX_LABEL, MPLS_LABEL_INVALID
+from vpp_papi_exceptions import CliFailedCommandError, CliSyntaxError,\
+    UnexpectedApiReturnValueError
 
 #
 # Dictionary keyed on message name to override default values for
@@ -106,19 +106,6 @@
     return ", ".join(f"{k}={v}" for k, v in d.items())
 
 
-class CliFailedCommandError(Exception):
-    """ cli command failed."""
-
-
-class CliSyntaxError(Exception):
-    """ cli command had a syntax error."""
-
-
-class UnexpectedApiReturnValueError(Exception):
-    """ exception raised when the API return value is unexpected """
-    pass
-
-
 class VppPapiProvider(object):
     """VPP-api provider using vpp-papi
 
@@ -287,7 +274,7 @@
                        reply.retval,
                        moves.reprlib.repr(reply))
                 self.test_class.logger.info(msg)
-                raise UnexpectedApiReturnValueError(msg)
+                raise UnexpectedApiReturnValueError(reply.retval, msg)
         elif self._expect_api_retval == self._zero:
             if hasattr(reply, 'retval') and reply.retval != expected_retval:
                 msg = "%s(%s) failed, expected %d return value instead " \
@@ -296,7 +283,7 @@
                                        expected_retval, reply.retval,
                                        repr(reply))
                 self.test_class.logger.info(msg)
-                raise UnexpectedApiReturnValueError(msg)
+                raise UnexpectedApiReturnValueError(reply.retval, msg)
         else:
             raise Exception("Internal error, unexpected value for "
                             "self._expect_api_retval %s" %