import sys
import os
import select
+import signal
import unittest
import tempfile
import time
import scapy.compat
from scapy.packet import Raw
-from hook import StepHook, PollHook, VppDiedError
+import hook as hookmodule
from vpp_pg_interface import VppPGInterface
from vpp_sub_interface import VppSubInterface
from vpp_lo_interface import VppLoInterface
SKIP = 3
TEST_RUN = 4
-debug_framework = False
-if os.getenv('TEST_DEBUG', "0") == "1":
- debug_framework = True
+
+class BoolEnvironmentVariable(object):
+
+ def __init__(self, env_var_name, default='n', true_values=None):
+ self.name = env_var_name
+ self.default = default
+ self.true_values = true_values if true_values is not None else \
+ ("y", "yes", "1")
+
+ def __bool__(self):
+ return os.getenv(self.name, self.default).lower() in self.true_values
+
+ if sys.version_info[0] == 2:
+ __nonzero__ = __bool__
+
+ def __repr__(self):
+ return 'BoolEnvironmentVariable(%r, default=%r, true_values=%r)' % \
+ (self.name, self.default, self.true_values)
+
+
+debug_framework = BoolEnvironmentVariable('TEST_DEBUG')
+if debug_framework:
import debug_internal
"""
"""
+class VppDiedError(Exception):
+ """ exception for reporting that the subprocess has died."""
+
+ signals_by_value = {v: k for k, v in signal.__dict__.items() if
+ k.startswith('SIG') and not k.startswith('SIG_')}
+
+ def __init__(self, rv=None, testcase=None, method_name=None):
+ self.rv = rv
+ self.signal_name = None
+ self.testcase = testcase
+ self.method_name = method_name
+
+ try:
+ self.signal_name = VppDiedError.signals_by_value[-rv]
+ except (KeyError, TypeError):
+ pass
+
+ if testcase is None and method_name is None:
+ in_msg = ''
+ else:
+ in_msg = 'running %s.%s ' % (testcase, method_name)
+
+ msg = "VPP subprocess died %sunexpectedly with return code: %d%s." % (
+ in_msg,
+ self.rv,
+ ' [%s]' % (self.signal_name if
+ self.signal_name is not None else ''))
+ super(VppDiedError, self).__init__(msg)
+
+
class _PacketInfo(object):
"""Private class to create packet info object.
def _is_skip_aarch64_set():
- return os.getenv('SKIP_AARCH64', 'n').lower() in ('yes', 'y', '1')
+ return BoolEnvironmentVariable('SKIP_AARCH64')
is_skip_aarch64_set = _is_skip_aarch64_set()
def _running_extended_tests():
- s = os.getenv("EXTENDED_TESTS", "n")
- return True if s.lower() in ("y", "yes", "1") else False
+ return BoolEnvironmentVariable("EXTENDED_TESTS")
running_extended_tests = _running_extended_tests()
@classmethod
def setUpConstants(cls):
""" Set-up the test case class based on environment variables """
- s = os.getenv("STEP", "n")
- cls.step = True if s.lower() in ("y", "yes", "1") else False
+ cls.step = BoolEnvironmentVariable('STEP')
d = os.getenv("DEBUG", None)
+ # inverted case to handle '' == True
c = os.getenv("CACHE_OUTPUT", "1")
cls.cache_vpp_output = False if c.lower() in ("n", "no", "0") else True
cls.set_debug_flags(d)
cls.vapi = VppPapiProvider(cls.shm_prefix, cls.shm_prefix, cls,
read_timeout)
if cls.step:
- hook = StepHook(cls)
+ hook = hookmodule.StepHook(cls)
else:
- hook = PollHook(cls)
+ hook = hookmodule.PollHook(cls)
cls.vapi.register_hook(hook)
cls.wait_for_stats_socket()
cls.statistics = VPPStats(socketname=cls.stats_sock)
"to 'continue' VPP from within gdb?", RED))
raise
except Exception:
- try:
- cls.quit()
- except Exception:
- pass
+
+ cls.quit()
raise
@classmethod
self.logger.info(self.statistics.set_errors_str())
self.logger.info(self.vapi.ppcli("show run"))
self.logger.info(self.vapi.ppcli("show log"))
+ self.logger.info(self.vapi.ppcli("show bihash"))
self.logger.info("Logging testcase specific show commands.")
self.show_commands_at_teardown()
self.registry.remove_vpp_config(self.logger)
super(VppTestCase, self).setUp()
self.reporter.send_keep_alive(self)
if self.vpp_dead:
- raise Exception("VPP is dead when setting up the test")
+
+ raise VppDiedError(rv=None, testcase=self.__class__.__name__,
+ method_name=self._testMethodName)
self.sleep(.1, "during setUp")
self.vpp_stdout_deque.append(
"--- test setUp() for %s.%s(%s) starts here ---\n" %
cls._captures = []
@classmethod
- def create_pg_interfaces(cls, interfaces):
+ def create_pg_interfaces(cls, interfaces, gso=0, gso_size=0):
"""
Create packet-generator interfaces.
"""
result = []
for i in interfaces:
- intf = VppPGInterface(cls, i)
+ intf = VppPGInterface(cls, i, gso, gso_size)
setattr(cls, intf.name, intf)
result.append(intf)
cls.pg_interfaces = result
def assert_packet_checksums_valid(self, packet,
ignore_zero_udp_checksums=True):
received = packet.__class__(scapy.compat.raw(packet))
- self.logger.debug(
- ppp("Verifying packet checksums for packet:", received))
udp_layers = ['UDP', 'UDPerror']
checksum_fields = ['cksum', 'chksum']
checksums = []
class Worker(Thread):
- def __init__(self, args, logger, env={}):
+ def __init__(self, args, logger, env=None):
self.logger = logger
self.args = args
+ self.process = None
self.result = None
+ env = {} if env is None else env
self.env = copy.deepcopy(env)
super(Worker, self).__init__()
def run(self):
executable = self.args[0]
+ if not os.path.exists(executable) or not os.access(
+ executable, os.F_OK | os.X_OK):
+ # Exit code that means some system file did not exist,
+ # could not be opened, or had some other kind of error.
+ self.result = os.EX_OSFILE
+ raise EnvironmentError(
+ "executable '%s' is not found or executable." % executable)
self.logger.debug("Running executable w/args `%s'" % self.args)
env = os.environ.copy()
env.update(self.env)