make test: fix RETRIES when setUpClass throws 86/13186/12
authorKlement Sekera <ksekera@cisco.com>
Fri, 22 Jun 2018 11:19:45 +0000 (13:19 +0200)
committerKlement Sekera <ksekera@cisco.com>
Mon, 25 Jun 2018 12:19:57 +0000 (14:19 +0200)
This change adds handling of special case when setUpClass throws. In
this case TestResults receives a mock object called _ErrorHolder.
By parsing its description, we find test class name and use it to lookup
the test class in test suite to be able to add it to the list of failures
for re-running.

Change-Id: I656f21e38aa450fc567cdcbcf6e586967f947a64
Signed-off-by: Klement Sekera <ksekera@cisco.com>
test/framework.py
test/run_tests.py

index dd4774d..fdaba2b 100644 (file)
@@ -957,7 +957,25 @@ class VppTestResult(unittest.TestResult):
         if hasattr(self, 'test_framework_failed_pipe'):
             pipe = self.test_framework_failed_pipe
             if pipe:
-                pipe.send(test.__class__)
+                if test.__class__.__name__ == "_ErrorHolder":
+                    x = str(test)
+                    if x.startswith("setUpClass"):
+                        # x looks like setUpClass (test_function.test_class)
+                        cls = x.split(".")[1].split(")")[0]
+                        for t in self.test_suite:
+                            if t.__class__.__name__ == cls:
+                                pipe.send(t.__class__)
+                                break
+                        else:
+                            raise Exception("Can't find class name `%s' "
+                                            "(from ErrorHolder) in test suite "
+                                            "`%s'" % (cls, self.test_suite))
+                    else:
+                        raise Exception("FIXME: unexpected special case - "
+                                        "ErrorHolder description is `%s'" %
+                                        str(test))
+                else:
+                    pipe.send(test.__class__)
 
     def addFailure(self, test, err):
         """
@@ -1192,6 +1210,8 @@ class VppTestRunner(unittest.TextTestRunner):
             filtered.countTestCases(), test.countTestCases()))
         if not running_extended_tests():
             print("Not running extended tests (some tests will be skipped)")
+        # super-ugly hack #2
+        VppTestResult.test_suite = filtered
         return super(VppTestRunner, self).run(filtered)
 
 
index 3476ef0..c21acab 100644 (file)
@@ -52,7 +52,10 @@ class Filter_by_class_list:
 
 def suite_from_failed(suite, failed):
     filter_cb = Filter_by_class_list(failed)
-    return VppTestRunner.filter_tests(suite, filter_cb)
+    suite = VppTestRunner.filter_tests(suite, filter_cb)
+    if 0 == suite.countTestCases():
+        raise Exception("Suite is empty after filtering out the failed tests!")
+    return suite
 
 
 def run_forked(suite):