import fnmatch
import time
from hook import Hook
+from collections import deque
# Sphinx creates auto-generated documentation by importing the python source
# files and collecting the docstrings from them. The NO_VPP_PAPI flag allows the
jsonfiles.append(os.path.join(root, filename))
self.papi = VPP(jsonfiles)
- self._events = list()
+ self._events = deque()
def register_hook(self, hook):
"""Replace hook registration with new hook
self.hook = hook
def collect_events(self):
+ """ Collect all events from the internal queue and clear the queue. """
e = self._events
- self._events = list()
+ self._events = deque()
return e
def wait_for_event(self, timeout, name=None):
+ """ Wait for and return next event. """
+ if self._events:
+ self.test_class.logger.debug("Not waiting, event already queued")
limit = time.time() + timeout
while time.time() < limit:
if self._events:
- e = self._events.pop(0)
+ e = self._events.popleft()
if name and type(e).__name__ != name:
raise Exception(
"Unexpected event received: %s, expected: %s" %
(type(e).__name__, name))
+ self.test_class.logger.debug("Returning event %s:%s" %
+ (name, e))
return e
time.sleep(0) # yield
if name is not None:
raise Exception("Event did not occur within timeout")
def __call__(self, name, event):
+ """ Enqueue event in the internal event queue. """
# FIXME use the name instead of relying on type(e).__name__ ?
# FIXME #2 if this throws, it is eaten silently, Ole?
+ self.test_class.logger.debug("New event: %s: %s" % (name, event))
self._events.append(event)
def connect(self):
self.papi.disconnect()
def api(self, api_fn, api_args, expected_retval=0):
- """Call API function and check it's return value
+ """ Call API function and check it's return value.
Call the appropriate hooks before and after the API call
:param api_fn: API function to call
if hasattr(reply, 'retval') and reply.retval != expected_retval:
msg = "API call failed, expected retval == %d, got %s" % (
expected_retval, repr(reply))
- self.test_class.logger.error(msg)
+ self.test_class.logger.info(msg)
raise Exception(msg)
self.hook.after_api(api_fn.__name__, api_args)
return reply
def cli(self, cli):
- """
- Execute a CLI, calling the before/after hooks appropriately.
+ """ Execute a CLI, calling the before/after hooks appropriately.
:param cli: CLI to execute
:returns: CLI output
return r.reply.decode().rstrip('\x00')
def ppcli(self, cli):
- """
- Helping method to print CLI command in case of info logging level.
+ """ Helper method to print CLI command in case of info logging level.
:param cli: CLI to execute
:returns: CLI output
return self.api(self.papi.sw_interface_dump, args)
def sw_interface_set_table(self, sw_if_index, is_ipv6, table_id):
- """
- Set the IPvX Table-id for the Interface
+ """ Set the IPvX Table-id for the Interface
:param sw_if_index:
:param is_ipv6:
'next_hop_via_label': next_hop_via_label,
'next_hop_out_label_stack': next_hop_out_label_stack})
+ def ip_fib_dump(self):
+ return self.api(self.papi.ip_fib_dump, {})
+
def ip_neighbor_add_del(self,
sw_if_index,
mac_address,
:param sw_if_index_from:
:param sw_if_index_to:
- :param enable
-
+ :param state:
"""
return self.api(self.papi.sw_interface_span_enable_disable,
{'sw_if_index_from': sw_if_index_from,
'enable_disable': enable_disable,
'pid': os.getpid(),
})
+
+ def classify_add_del_table(
+ self,
+ is_add,
+ mask,
+ match_n_vectors=1,
+ table_index=0xFFFFFFFF,
+ nbuckets=2,
+ memory_size=2097152,
+ skip_n_vectors=0,
+ next_table_index=0xFFFFFFFF,
+ miss_next_index=0xFFFFFFFF,
+ current_data_flag=0,
+ current_data_offset=0):
+
+ """
+ :param is_add:
+ :param mask:
+ :param match_n_vectors (Default value = 1):
+ :param table_index (Default value = 0xFFFFFFFF)
+ :param nbuckets: (Default value = 2)
+ :param memory_size: (Default value = 2097152)
+ :param skip_n_vectors: (Default value = 0)
+ :param next_table_index: (Default value = 0xFFFFFFFF)
+ :param miss_next_index: (Default value = 0xFFFFFFFF)
+ :param current_data_flag: (Default value = 0)
+ :param current_data_offset: (Default value = 0)
+ """
+
+ return self.api(
+ self.papi.classify_add_del_table,
+ {'is_add' : is_add,
+ 'table_index' : table_index,
+ 'nbuckets' : nbuckets,
+ 'memory_size': memory_size,
+ 'skip_n_vectors' : skip_n_vectors,
+ 'match_n_vectors' : match_n_vectors,
+ 'next_table_index' : next_table_index,
+ 'miss_next_index' : miss_next_index,
+ 'current_data_flag' : current_data_flag,
+ 'current_data_offset' : current_data_offset,
+ 'mask' : mask})
+
+ def classify_add_del_session(
+ self,
+ is_add,
+ table_index,
+ match,
+ opaque_index=0xFFFFFFFF,
+ hit_next_index=0xFFFFFFFF,
+ advance=0,
+ action=0,
+ metadata=0):
+ """
+ :param is_add:
+ :param table_index:
+ :param match:
+ :param opaque_index: (Default value = 0xFFFFFFFF)
+ :param hit_next_index: (Default value = 0xFFFFFFFF)
+ :param advance: (Default value = 0)
+ :param action: (Default value = 0)
+ :param metadata: (Default value = 0)
+ """
+
+ return self.api(
+ self.papi.classify_add_del_session,
+ {'is_add' : is_add,
+ 'table_index' : table_index,
+ 'hit_next_index' : hit_next_index,
+ 'opaque_index' : opaque_index,
+ 'advance' : advance,
+ 'action' : action,
+ 'metadata' : metadata,
+ 'match' : match})
+
+ def input_acl_set_interface(
+ self,
+ is_add,
+ sw_if_index,
+ ip4_table_index=0xFFFFFFFF,
+ ip6_table_index=0xFFFFFFFF,
+ l2_table_index=0xFFFFFFFF):
+ """
+ :param is_add:
+ :param sw_if_index:
+ :param ip4_table_index: (Default value = 0xFFFFFFFF)
+ :param ip6_table_index: (Default value = 0xFFFFFFFF)
+ :param l2_table_index: (Default value = 0xFFFFFFFF)
+ """
+
+ return self.api(
+ self.papi.input_acl_set_interface,
+ {'sw_if_index' : sw_if_index,
+ 'ip4_table_index' : ip4_table_index,
+ 'ip6_table_index' : ip6_table_index,
+ 'l2_table_index' : l2_table_index,
+ 'is_add' : is_add})