[apparmor] [patch] add better loop support to common_test.py
Steve Beattie
steve at nxnw.org
Tue Mar 31 08:36:10 UTC 2015
Hi,
Sorry for the delay in reviewing.
On Fri, Mar 06, 2015 at 11:57:11PM +0100, Christian Boltz wrote:
> It turned out that adding
> from apparmor.aa import AppArmorException
> in test-*.py explodes with
>
> Traceback (most recent call last):
> File "test-example.py", line 45, in <module>
> setup_all_tests()
> File "/home/cb/apparmor/HEAD-clean/utils/test/common_test.py", line 58, in setup_all_tests
> if inspect.isclass(obj) and (isinstance(obj(), unittest.TestCase)):
> TypeError: __init__() missing 1 required positional argument: 'value'
>
> The reason for this is that AppArmorException __init__() has an additional
> parameter. This means we have to wrap "obj()" in try/except. Fortunately
> this affects only non-test classes :-)
>
> Since Seth seems to be out of counter-arguments for
> 12-test-loop-simplify.diff, I also merged it into this patch.
> (It also affects another patch, which I'll resend in a minute.)
>
>
> Here's v3, this time with the number included in the filename ;-)
Unfortunately, this doesn't appear to work under python2:
$ PYTHONPATH=.. python2 test-example.py
Traceback (most recent call last):
File "test-example.py", line 44, in <module>
setup_all_tests()
File "/home/steve/bzr/apparmor-master/utils/test/common_test.py", line 60, in setup_all_tests
obj_instance = obj() # will fail for (non-test) classes with additional __init__ parameters
File "/usr/lib/python2.7/unittest/case.py", line 189, in __init__
(self.__class__, methodName))
ValueError: no such test method in <class 'common_test.AATest'>: runTest
I suspect this has to do with the differences in how objects are
internally implemented between python 2 and python 3.
And while python 3 has gotten wider support and I would like to
eventually drop support for python 2.7, I don't think we can justify
doing so quite yet.
> [ 07-common_test_better_loop_support.diff ]
>
> === modified file 'utils/test/common_test.py'
> --- utils/test/common_test.py 2014-11-06 20:32:49 +0000
> +++ utils/test/common_test.py 2015-03-03 23:37:48 +0000
> @@ -1,5 +1,6 @@
> # ----------------------------------------------------------------------
> # Copyright (C) 2013 Kshitij Gupta <kgupta8592 at gmail.com>
> +# Copyright (C) 2015 Christian Boltz <apparmor at cboltz.de>
> #
> # This program is free software; you can redistribute it and/or
> # modify it under the terms of version 2 of the GNU General Public
> @@ -12,6 +13,8 @@
> #
> # ----------------------------------------------------------------------
> import unittest
> +import inspect
> import os
> import re
> +import sys
>
> @@ -34,6 +36,10 @@
> # print("Please press the Y button on the keyboard.")
> # self.assertEqual(apparmor.common.readkey().lower(), 'y', 'Error reading key from shell!')
>
> +
> +class AATest(unittest.TestCase):
> + tests = []
> +
> class AAParseTest(unittest.TestCase):
> parse_function = None
>
> @@ -44,6 +50,37 @@
> 'parse object %s returned "%s", expected "%s"' \
> %(self.parse_function.__doc__, parsed.serialize(), rule))
>
> +
> +def setup_all_tests():
> + '''call setup_tests_loop() for each class in module_name'''
> + for name, obj in inspect.getmembers(sys.modules['__main__']):
> + if inspect.isclass(obj):
> + try:
> + obj_instance = obj() # will fail for (non-test) classes with additional __init__ parameters
> + except TypeError:
> + obj_instance = None
> + if obj_instance and isinstance(obj_instance, unittest.TestCase):
> + setup_tests_loop(obj)
> +
> +def setup_tests_loop(test_class):
> + '''Create tests in test_class using test_class.tests and self._run_test()
> +
> + test_class.tests should be tuples of (test_data, expected_results)
> + test_data and expected_results can be of any type as long as test_class._run_test()
> + know how to handle them.
> +
> + A typical definition for _run_test() is:
> + def test_class._run_test(self, test_data, expected)
> + '''
> +
> + for (i, (test_data, expected)) in enumerate(test_class.tests):
> + def stub_test(self, test_data=test_data, expected=expected):
> + self._run_test(test_data, expected)
> +
> + stub_test.__doc__ = "test '%s'" % (test_data)
> + setattr(test_class, 'test_%d' % (i), stub_test)
> +
> +
> def setup_regex_tests(test_class):
> '''Create tests in test_class using test_class.tests and AAParseTest._test_parse_rule()
>
>
> === added file 'utils/test/test-example.py'
> --- utils/test/test-example.py 1970-01-01 00:00:00 +0000
> +++ utils/test/test-example.py 2015-03-03 21:05:18 +0000
> @@ -0,0 +1,45 @@
> +#! /usr/bin/env python
> +# ------------------------------------------------------------------
> +#
> +# Copyright (C) 2015 Christian Boltz <apparmor at cboltz.de>
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of version 2 of the GNU General Public
> +# License published by the Free Software Foundation.
> +#
> +# ------------------------------------------------------------------
> +
> +import unittest
> +from common_test import AATest, setup_all_tests
> +
> +class TestFoo(AATest):
> + tests = [
> + (0, 0 ),
> + (42, 42),
> + ]
> +
> + def _run_test(self, params, expected):
> + self.assertEqual(params, expected)
> +
> +class TestBar(AATest):
> + tests = [
> + ('a', 'foo'),
> + ('b', 'bar'),
> + ('c', 'baz'),
> + ]
> +
> + def _run_test(self, params, expected):
> + self.assertNotEqual(params, expected)
> +
> + def testAdditionalBarTest(self):
> + self.assertEqual(1, 1)
> +
> +class TestBaz(AATest):
> + def test_Baz_only_one_test(self):
> + self.assertEqual("baz", "baz")
> +
> +
> +
> +if __name__ == '__main__':
> + setup_all_tests()
> + unittest.main(verbosity=2)
--
Steve Beattie
<sbeattie at ubuntu.com>
http://NxNW.org/~steve/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20150331/c376a434/attachment.pgp>
More information about the AppArmor
mailing list