From 6e7aabc780ff9f70bf05d41b97cc973451e0b2ee Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 16 Jun 2016 18:59:13 -0400 Subject: Convert timing report to integrate with unittest.TextTestRunner, to avoid garbled reports if a test fails. --- unit_tests.py | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/unit_tests.py b/unit_tests.py index efda5e9..b15d7a7 100644 --- a/unit_tests.py +++ b/unit_tests.py @@ -21,14 +21,16 @@ except ImportError: def log(msg): if not args.quiet: - sys.stderr.write("{}\n".format(msg)) + sys.stderr.write(msg) + sys.stderr.write("\n") + def main(): from sys import argv global args args = parse_arguments(argv[1:]) argv = argv[:1] + args.only_test - unittest.main(verbosity = 1 if args.quiet else 2, argv = argv, catchbreak = True) + unittest.main(verbosity = 1 if args.quiet else 2, argv = argv, catchbreak = True, testRunner = TextTestRunner) def parse_arguments(argv = ()): from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter @@ -121,31 +123,31 @@ def tearDownModule(): check_call(("sudo", "kill", str(rpc.pid))) -class TimedTestCase(unittest.TestCase): - """ - TestCase subclass with setUp and tearDown hooks to report - individual test duration. - """ +# Subclass a few bits of unittest to add timing reports for individual tests. + +class TestCase(unittest.TestCase): def setUp(self): - super(TimedTestCase, self).setUp() - self.addCleanup(self._print_timing) + super(TestCase, self).setUp() self.startTime = datetime.datetime.now() def tearDown(self): self.endTime = datetime.datetime.now() - super(TimedTestCase, self).tearDown() + super(TestCase, self).tearDown() - def _print_timing(self): - try: - elapsed = self.endTime - self.startTime - except AttributeError: - pass - else: - log("Runtime {}".format(elapsed)) +class TextTestResult(unittest.TextTestResult): + + def addSuccess(self, test): + if self.showAll and hasattr(test, "startTime") and hasattr(test, "endTime"): + self.stream.write("runtime {} ... ".format(test.endTime - test.startTime)) + self.stream.flush() + super(TextTestResult, self).addSuccess(test) +class TextTestRunner(unittest.TextTestRunner): + resultclass = TextTestResult -class TestInit(TimedTestCase): + +class TestInit(TestCase): """ Test all the flavors of C_Initialize(). """ @@ -173,7 +175,7 @@ class TestInit(TimedTestCase): p11.C_Finalize() -class TestDevice(TimedTestCase): +class TestDevice(TestCase): """ Test basic device stuff like C_GetSlotList(), C_OpenSession(), and C_Login(). """ @@ -254,7 +256,7 @@ class TestDevice(TimedTestCase): p11.C_FindObjectsFinal(session) -class TestKeys(TimedTestCase): +class TestKeys(TestCase): """ Tests involving keys. """ @@ -549,6 +551,8 @@ class TestKeys(TimedTestCase): @unittest.skipUnless(pycrypto_loaded, "requires PyCrypto") def test_load_sign_verify_rsa_3416(self): "Load/sign/verify with RSA-3416-SHA-512 and externally-supplied key" + if not args.all_tests: + self.skipTest("Key length not a multiple of 32, so expected to fail (fairly quickly)") public_key, private_key = self._load_rsa_keypair(rsa_3416_pem, "RSA-3416") hamster = "Your mother was a hamster" p11.C_SignInit(self.session, CKM_SHA512_RSA_PKCS, private_key) -- cgit v1.2.3