tests: refactor VppDiedError. 64/20264/6
authorPaul Vinciguerra <pvinci@vinciconsulting.com>
Thu, 20 Jun 2019 16:24:12 +0000 (12:24 -0400)
committerAndrew Yourtchenko <ayourtch@gmail.com>
Mon, 24 Jun 2019 16:03:09 +0000 (16:03 +0000)
- Move Exception into same module as TestCase.
- Move the error reporting logic inside the error.
- Allows testing of the returncode and signal_name for tests to consume.
- Fix the signal reporting code:
VppDiedError: VPP subprocess died unexpectedly with returncode -6 [unknown].
    displays as:
VppDiedError: VPP subprocess died unexpectedly with return code: -6 [SIGABRT].

Type: test

Change-Id: I8488ab318a596c9b737308829cedfb7e96e57302
Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
MAINTAINERS
test/framework.py
test/hook.py
test/sanity_run_vpp.py

index 1943c0f..bb62ca3 100644 (file)
@@ -332,7 +332,11 @@ M: Dave Barach <dave@barachs.net>
 F:     src/plugins/nsim/
 
 Test Infrastructure
+<<<<<<< HEAD
 I:  tests
+=======
+I:     tests
+>>>>>>> d84661c... tests: refactor VppDiedError.
 M:     Klement Sekera <ksekera@cisco.com>
 M:     Paul Vinciguerra <pvinci@vinciconsulting.com>
 F:     test/
index 26e93e4..00fee86 100644 (file)
@@ -5,6 +5,7 @@ import gc
 import sys
 import os
 import select
+import signal
 import unittest
 import tempfile
 import time
@@ -21,7 +22,7 @@ from logging import FileHandler, DEBUG, Formatter
 
 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
@@ -69,6 +70,27 @@ if os.getenv('TEST_DEBUG', "0") == "1":
 """
 
 
+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):
+        self.rv = rv
+        self.signal_name = None
+        try:
+            self.signal_name = VppDiedError.signals_by_value[-rv]
+        except KeyError:
+            pass
+
+        msg = "VPP subprocess died unexpectedly with return code: %d%s." % (
+            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.
 
@@ -492,9 +514,9 @@ class VppTestCase(unittest.TestCase):
             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)
@@ -519,10 +541,8 @@ class VppTestCase(unittest.TestCase):
                                    "to 'continue' VPP from within gdb?", RED))
                 raise
         except Exception:
-            try:
-                cls.quit()
-            except Exception:
-                pass
+
+            cls.quit()
             raise
 
     @classmethod
index ccc5c86..97b05d0 100644 (file)
@@ -1,13 +1,12 @@
-import signal
 import os
 import sys
 import traceback
-from log import RED, single_line_delim, double_line_delim
 import ipaddress
 from subprocess import check_output, CalledProcessError
 
 import scapy.compat
-
+import framework
+from log import RED, single_line_delim, double_line_delim
 from util import check_core_path, get_core_path
 
 
@@ -72,10 +71,6 @@ class Hook(object):
         pass
 
 
-class VppDiedError(Exception):
-    pass
-
-
 class PollHook(Hook):
     """ Hook which checks if the vpp subprocess is alive """
 
@@ -117,22 +112,11 @@ class PollHook(Hook):
 
         self.test.vpp.poll()
         if self.test.vpp.returncode is not None:
-            signaldict = dict(
-                (k, v) for v, k in reversed(sorted(signal.__dict__.items()))
-                if v.startswith('SIG') and not v.startswith('SIG_'))
-
-            if self.test.vpp.returncode in signaldict:
-                s = signaldict[abs(self.test.vpp.returncode)]
-            else:
-                s = "unknown"
-            msg = "VPP subprocess died unexpectedly with returncode %d [%s]." \
-                  % (self.test.vpp.returncode, s)
-            self.logger.critical(msg)
+            self.test.vpp_dead = True
+            raise framework.VppDiedError(rv=self.test.vpp.returncode)
             core_path = get_core_path(self.test.tempdir)
             if os.path.isfile(core_path):
                 self.on_crash(core_path)
-            self.test.vpp_dead = True
-            raise VppDiedError(msg)
 
     def before_api(self, api_name, api_args):
         """
index d1c2987..92f250b 100644 (file)
@@ -3,8 +3,7 @@
 from __future__ import print_function
 from multiprocessing import Pipe
 from sys import exit
-from hook import VppDiedError
-from framework import VppTestCase, KeepAliveReporter
+from framework import VppDiedError, VppTestCase, KeepAliveReporter
 
 
 class SanityTestCase(VppTestCase):