Hello,

this patch adds a testsuite for the capability rule class (including the 
base class). Since I'm writing these classes test-driven, the testsuite 
covers 100% of the rule/*.py code :-)

Note that the testsuite also documents two known issues (commented out):

a) 
If you use covered_raw('capability foo bar,') and your profile has 
"capability foo, capability bar,", covered_raw will not detect it. The 
reason for this is that "capability foo, capability bar," is split over 
two capability_rule objects internally.

However it works the other way round - if the profile has "capability 
foo bar", covered_raw("capability foo") and covered_raw("capability foo 
bar",) and even "covered_raw("capability bar foo,") will find it.

That's a corner case and the only problem it can cause is a superfluous 
line in a (hand-modified, we don't write multi-capability lines) 
profile, so I'm not sure if it's worth fixing it

b)
When deleting duplicates, "capability," will delete all "capability 
foo," rules. However it doesn't delete "allow capability foo," rules. 
(I didn't check the reason for this yet.)

(The included good news is that "capability," is now recogniced as "all 
capabilities" :-)


Regards,

Christian Boltz
-- 
[SuSE 9.1] Und utf-8 saugt tote Hamster durch Strohhalme, selbst wenn
es funktioniert. [...] Und das alles nur, damit ich Klingonisch native
verarbeiten kann in meinem Rechner.
[http://blog.koehntopp.de/archives/317_Die+schlimmste+aller+Susen.html]
=== added file 'utils/test/test-capability.py'
--- utils/test/test-capability.py	1970-01-01 00:00:00 +0000
+++ utils/test/test-capability.py	2014-11-15 21:48:16 +0000
@@ -0,0 +1,657 @@
+#!/usr/bin/env python
+# ----------------------------------------------------------------------
+#    Copyright (C) 2014 Christian Boltz <[email protected]>
+#
+#    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 as published by the Free Software Foundation.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+# ----------------------------------------------------------------------
+
+import unittest
+
+from apparmor.rule.capability import capability_rule, capability_rules
+from apparmor.aa import ALL
+from apparmor.common import AppArmorException, AppArmorBug, hasher
+from apparmor.logparser import ReadLog
+
+import re
+
+# --- tests for single capability_rule --- #
+
+class CapabilityTest(unittest.TestCase):
+    def _compare_obj_with_rawrule(self, rawrule, expected):
+
+        obj = capability_rule()
+        obj.set_raw(rawrule)
+
+        self.assertEqual(rawrule.strip(), obj.rawrule)
+
+        self._compare_obj(obj, expected)
+
+    def _compare_obj(self, obj, expected):
+        self.assertEqual(expected['allow_keyword'], obj.allow_keyword)
+        self.assertEqual(expected['audit'], obj.audit)
+        self.assertEqual(expected['capability'], obj.capability)
+        self.assertEqual(expected['deny'], obj.deny)
+        self.assertEqual(expected['inlinecomment'], obj.inlinecomment)
+
+    def test_cap_allow_all(self):
+        self._compare_obj_with_rawrule("capability,", {
+            'allow_keyword':    False,
+            'deny':             False,
+            'audit':            False,
+            'capability':       [ ALL ],
+            'inlinecomment':    "",
+        })
+
+    def test_cap_allow_sys_admin(self):
+        self._compare_obj_with_rawrule("capability sys_admin,", {
+            'allow_keyword':    False,
+            'deny':             False,
+            'audit':            False,
+            'capability':       [ 'sys_admin' ],
+            'inlinecomment':    "",
+        })
+
+    def test_cap_deny_sys_admin(self):
+        self._compare_obj_with_rawrule("     deny capability sys_admin,  # some comment", {
+            'allow_keyword':    False,
+            'deny':             True,
+            'audit':            False,
+            'capability':       [ 'sys_admin' ],
+            'inlinecomment':    " # some comment",
+        })
+
+    # Template for test_cap_* functions
+    #    def test_cap_(self):
+    #        self._compare_obj_with_rawrule("capability", {
+    #            'allow_keyword':    False,
+    #            'deny':             False,
+    #            'audit':            False,
+    #            'capability':       [],
+    #            'inlinecomment':    "",
+    #        })
+
+    def test_cap_from_log(self):
+        parser = ReadLog('', '', '', '', '')
+        event = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13  capname="net_raw"'
+
+        parsed_event = parser.parse_event(event)
+
+        self.assertEqual(parsed_event, {
+            'request_mask': set(),
+            'denied_mask': set(),
+            'magic_token': 0,
+            'parent': 0,
+            'profile': '/bin/ping',
+            'operation': 'capable',
+            'resource': None,
+            'info': None,
+            'aamode': 'PERMITTING',
+            'time': 1415403814,
+            'active_hat': None,
+            'pid': 15454,
+            'task': 0,
+            'attr': None,
+            'name2': None,
+            'name': 'net_raw'
+        })
+
+        obj = capability_rule()
+        obj.set_log(parsed_event)
+
+        self._compare_obj(obj, {
+            'allow_keyword':    False,
+            'deny':             False,
+            'audit':            False,
+            'capability':       ['net_raw'],
+            'inlinecomment':    "",
+        })
+
+        self.assertEqual(obj.get_raw(1), '  capability net_raw,')
+
+    def test_cap_from_invalid_log(self):
+        parser = ReadLog('', '', '', '', '')
+        # invalid log entry, name= should contain the capability name
+        event = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13  capname=""'
+
+        parsed_event = parser.parse_event(event)
+
+        obj = capability_rule()
+
+        with self.assertRaises(AppArmorBug):
+            obj.set_log(parsed_event)
+
+        with self.assertRaises(AppArmorBug):
+            obj.get_raw(1)
+
+    def test_cap_from_non_cap_log(self):
+        parser = ReadLog('', '', '', '', '')
+        # log entry for different rule type
+        event = 'type=AVC msg=audit(1415403814.973:667): apparmor="ALLOWED" operation="setsockopt" profile="/home/sys-tmp/ping" pid=15454 comm="ping" lport=1 family="inet" sock_type="raw" protocol=1'
+
+        parsed_event = parser.parse_event(event)
+
+        obj = capability_rule()
+
+        with self.assertRaises(AppArmorBug):
+            obj.set_log(parsed_event)
+
+        with self.assertRaises(AppArmorBug):
+            obj.get_raw(1)
+
+
+class InvalidCapabilityTest(unittest.TestCase):
+    def _check_invalid_rawrule(self, rawrule):
+        obj = capability_rule()
+        with self.assertRaises(AppArmorException):
+            obj.set_raw(rawrule)
+
+    def test_invalid_cap_missing_comma(self):
+        self._check_invalid_rawrule('capability')  # missing comma
+
+    def test_invalid_cap_non_capability_rule(self):
+        self._check_invalid_rawrule('network,')  # not a capability rule
+
+    def test_empty_cap_list(self):
+        obj = capability_rule()
+        # no capability set, and ALL not set
+        with self.assertRaises(AppArmorBug):
+            obj.get_clean(1)
+
+    def test_space_cap(self):
+        obj = capability_rule()
+        obj.capability.append('  ')  # the whitespace capability ;-)
+        with self.assertRaises(AppArmorBug):
+            obj.get_clean(1)
+
+    def test_parse_audit_allow_invalid(self):
+        obj = capability_rule()
+
+        regex = re.compile('^\s*(?P<audit>audit\s+)?(?P<allow>allow\s+|deny\s+|invalid\s+)?')
+        matches = regex.search('audit invalid ')
+
+        with self.assertRaises(AppArmorBug):
+            obj.parse_audit_allow(matches)
+
+
+class WriteCapabilityTest(unittest.TestCase):
+    def _check_write_rule(self, rawrule, cleanrule):
+        obj = capability_rule()
+        obj.set_raw(rawrule)
+        clean = obj.get_clean(0)
+        raw = obj.get_raw(0)
+
+        self.assertEqual(cleanrule.strip(), clean, 'unexpected clean rule')
+        self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
+
+    def test_write_all(self):
+        self._check_write_rule('     capability      ,    # foo        ', 'capability, # foo')
+
+    def test_write_sys_admin(self):
+        self._check_write_rule('    audit     capability sys_admin,', 'audit capability sys_admin,')
+
+    def test_write_sys_multi(self):
+        self._check_write_rule('   deny capability      sys_admin      audit_write,# foo bar', 'deny capability audit_write sys_admin, # foo bar')
+
+    def test_write_manually(self):
+        obj = capability_rule()
+        obj.capability = ['ptrace', 'audit_write']
+        obj.allow_keyword = True
+
+        expected = '    allow capability audit_write ptrace,'
+
+        self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule')
+        self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule')
+
+class CapabilityCoveredTest(unittest.TestCase):
+    def _init_obj_with_rawrule(self, rawrule):
+        obj = capability_rule()
+        obj.set_raw(rawrule)
+        return obj
+
+    def _is_covered(self, obj, rule_to_test):
+        return obj.covered(self._init_obj_with_rawrule(rule_to_test))
+
+    def _is_covered_exact(self, obj, rule_to_test):
+        return obj.covered(self._init_obj_with_rawrule(rule_to_test), True, True)
+
+    def test_covered_single(self):
+        obj = self._init_obj_with_rawrule('capability sys_admin,')
+
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin,'))
+
+        self.assertFalse(self._is_covered(obj, 'audit capability sys_admin,'))
+        self.assertFalse(self._is_covered(obj, 'audit capability,'))
+        self.assertFalse(self._is_covered(obj, 'capability chown,'))
+        self.assertFalse(self._is_covered(obj, 'capability,'))
+
+    def test_covered_audit(self):
+        obj = self._init_obj_with_rawrule('audit capability sys_admin,')
+
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin,'))
+        self.assertTrue(self._is_covered(obj, 'audit capability sys_admin,'))
+
+        self.assertFalse(self._is_covered(obj, 'audit capability,'))
+        self.assertFalse(self._is_covered(obj, 'capability chown,'))
+        self.assertFalse(self._is_covered(obj, 'capability,'))
+
+    def test_covered_check_audit(self):
+        obj = self._init_obj_with_rawrule('audit capability sys_admin,')
+
+        self.assertFalse(self._is_covered_exact(obj, 'capability sys_admin,'))
+        self.assertTrue(self._is_covered_exact(obj, 'audit capability sys_admin,'))
+
+        self.assertFalse(self._is_covered_exact(obj, 'audit capability,'))
+        self.assertFalse(self._is_covered_exact(obj, 'capability chown,'))
+        self.assertFalse(self._is_covered_exact(obj, 'capability,'))
+
+
+    def test_covered_multi(self):
+        obj = self._init_obj_with_rawrule('capability audit_write sys_admin,')
+
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin,'))
+        self.assertTrue(self._is_covered(obj, 'capability audit_write,'))
+        self.assertTrue(self._is_covered(obj, 'capability audit_write sys_admin,'))
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin audit_write,'))
+
+        self.assertFalse(self._is_covered(obj, 'audit capability,'))
+        self.assertFalse(self._is_covered(obj, 'capability chown,'))
+        self.assertFalse(self._is_covered(obj, 'capability,'))
+
+    def test_covered_all(self):
+        obj = self._init_obj_with_rawrule('capability,')
+
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin,'))
+        self.assertTrue(self._is_covered(obj, 'capability audit_write,'))
+        self.assertTrue(self._is_covered(obj, 'capability audit_write sys_admin,'))
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin audit_write,'))
+        self.assertTrue(self._is_covered(obj, 'capability,'))
+
+        self.assertFalse(self._is_covered(obj, 'audit capability,'))
+
+    def test_covered_deny(self):
+        obj = self._init_obj_with_rawrule('capability sys_admin,')
+
+        self.assertTrue(self._is_covered(obj, 'capability sys_admin,'))
+
+        self.assertFalse(self._is_covered(obj, 'audit deny capability sys_admin,'))
+        self.assertFalse(self._is_covered(obj, 'deny capability sys_admin,'))
+        self.assertFalse(self._is_covered(obj, 'capability chown,'))
+        self.assertFalse(self._is_covered(obj, 'capability,'))
+
+    def test_covered_deny_2(self):
+        obj = self._init_obj_with_rawrule('deny capability sys_admin,')
+
+        self.assertTrue(self._is_covered(obj, 'deny capability sys_admin,'))
+
+        self.assertFalse(self._is_covered(obj, 'audit deny capability sys_admin,'))
+        self.assertFalse(self._is_covered(obj, 'capability sys_admin,'))
+        self.assertFalse(self._is_covered(obj, 'deny capability chown,'))
+        self.assertFalse(self._is_covered(obj, 'deny capability,'))
+
+    def test_invalid_covered_obj(self):
+        obj = self._init_obj_with_rawrule('capability sys_admin,')
+
+        testobj = capability_rule()  # no capability set
+
+        with self.assertRaises(AppArmorBug):
+            obj.covered(testobj)
+
+    def test_empty_init(self):
+        obj = capability_rule()
+        obj.capability.append('sys_admin')
+
+        obj2 = capability_rule()
+        obj2.capability.append('ptrace')
+
+        self.assertFalse(self._is_covered(obj2, 'capability sys_admin,'))
+        self.assertTrue(self._is_covered(obj2, 'capability ptrace,'))
+
+# --- tests for capability_rules --- #
+
+class CapabilityRulesTest(unittest.TestCase):
+    def test_empty_collection(self):
+        col = capability_rules()
+        col2 = capability_rules()
+        self.assertEqual([], col.get_raw(2))
+        self.assertEqual([], col.get_clean(2))
+        self.assertEqual([], col2.get_raw(2))
+        self.assertEqual([], col2.get_clean(2))
+
+    def test_collection_1(self):
+        col = capability_rules()
+        rules = [
+            'capability sys_admin,',
+            'capability chown,',
+        ]
+
+        expected_raw = [
+            'capability sys_admin,',
+            'capability chown,',
+            '',
+        ]
+
+        expected_clean = [
+            'capability chown,',
+            'capability sys_admin,',
+            '',
+        ]
+
+        for rule in rules:
+            col.add_raw(rule)
+
+        self.assertEqual(expected_raw, col.get_raw(0))
+        self.assertEqual(expected_clean, col.get_clean(0))
+
+    def test_collection_2(self):
+        col = capability_rules()
+        rules = [
+            'capability chown,',
+            'allow capability sys_admin,',
+            'deny capability chgrp, # example comment',
+        ]
+
+        expected_raw = [
+            '  capability chown,',
+            '  allow capability sys_admin,',
+            '  deny capability chgrp, # example comment',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  allow capability sys_admin,',
+            '  capability chown,',
+            '',
+        ]
+
+        for rule in rules:
+            col.add_raw(rule)
+
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+class CapabilityRulesCoveredTest(unittest.TestCase):
+    def test_collection_covered_raw(self):
+        col = capability_rules()
+        rules = [
+            'capability chown,',
+            'capability setuid setgid,',
+            'allow capability sys_admin,',
+            'audit capability kill,',
+            'deny capability chgrp, # example comment',
+        ]
+
+        for rule in rules:
+            col.add_raw(rule)
+
+        self.assertTrue(col.covered_raw('capability chown,'))
+        self.assertTrue(col.covered_raw('capability sys_admin,'))
+        self.assertTrue(col.covered_raw('allow capability sys_admin,'))
+        self.assertTrue(col.covered_raw('capability setuid,'))
+        self.assertTrue(col.covered_raw('allow capability setgid,'))
+        self.assertTrue(col.covered_raw('capability setgid setuid,'))
+        # self.assertTrue(col.covered_raw('capability sys_admin chown,'))  # fails because it is split over two rule objects internally
+        self.assertTrue(col.covered_raw('capability kill,'))
+
+        self.assertFalse(col.covered_raw('deny capability chown,'))
+        self.assertFalse(col.covered_raw('deny capability sys_admin,'))
+        self.assertFalse(col.covered_raw('deny capability sys_admin chown,'))
+        self.assertFalse(col.covered_raw('deny capability setgid,'))
+        self.assertFalse(col.covered_raw('deny capability kill,'))
+
+        self.assertFalse(col.covered_raw('audit capability chown,'))
+        self.assertFalse(col.covered_raw('audit capability sys_admin,'))
+        self.assertFalse(col.covered_raw('audit capability sys_admin chown,'))
+        self.assertFalse(col.covered_raw('audit capability setgid,'))
+        self.assertTrue(col.covered_raw('audit capability kill,'))
+
+        self.assertTrue(col.covered_raw('deny capability chgrp,'))
+        self.assertFalse(col.covered_raw('audit deny capability chgrp,'))
+        self.assertFalse(col.covered_raw('audit capability chgrp,'))
+
+    def test_collection_covered_raw_2(self):
+        col = capability_rules()
+        rules = [
+            'capability chown,',
+            'capability setuid setgid,',
+            'allow capability sys_admin,',
+            'audit capability kill,',
+            'deny capability chgrp, # example comment',
+        ]
+
+        for rule in rules:
+            col.add_raw(rule)
+
+        event_base = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13  capname="%s"'
+
+        parser = ReadLog('', '', '', '', '')
+
+        self.assertFalse(col.covered_log(parser.parse_event(event_base%'net_raw')))
+        self.assertTrue(col.covered_log(parser.parse_event(event_base%'chown')))
+        self.assertTrue(col.covered_log(parser.parse_event(event_base%'sys_admin')))
+        self.assertTrue(col.covered_log(parser.parse_event(event_base%'kill')))
+        self.assertFalse(col.covered_log(parser.parse_event(event_base%'chgrp')))
+        self.assertTrue(col.covered_log(parser.parse_event(event_base%'chgrp'), False))  # ignores allow/deny
+
+class CapabilityGlobTest(unittest.TestCase):
+    def test_glob(self):
+        col = capability_rules()
+        self.assertEqual(col.get_glob('capability net_raw,'), 'capability,')
+
+    def test_glob_ext(self):
+        col = capability_rules()
+
+        with self.assertRaises(AppArmorBug):
+            col.get_glob_ext('capability net_raw,')
+
+class CapabilityDeleteTest(unittest.TestCase):
+    def _setup_testcol(self):
+        col = capability_rules()
+        rules = [
+            'capability chown,',
+            'allow capability sys_admin,',
+            'deny capability chgrp, # example comment',
+        ]
+
+        for rule in rules:
+            col.add_raw(rule)
+
+        return col
+
+    def test_delete_raw(self):
+        expected_raw = [
+            '  capability chown,',
+            '  deny capability chgrp, # example comment',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  capability chown,',
+            '',
+        ]
+
+        col = self._setup_testcol()
+        col.delete_raw('capability sys_admin,')
+
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+    def test_delete_raw_notfound(self):
+        col = self._setup_testcol()
+
+        with self.assertRaises(AppArmorBug):
+            col.delete_raw('capability audit_write,')
+
+    def test_delete_duplicates(self):
+        col = self._setup_testcol()
+
+        inc = capability_rules()
+        rules = [
+            'capability chown,',
+            'deny capability chgrp, # example comment',
+        ]
+
+        for rule in rules:
+            inc.add_raw(rule)
+
+        expected_raw = [
+            '  allow capability sys_admin,',
+            '',
+        ]
+
+        expected_clean = expected_raw
+
+        self.assertEqual(col.delete_duplicates(inc), 2)
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+    def test_delete_duplicates_2(self):
+        col = self._setup_testcol()
+
+        inc = capability_rules()
+        rules = [
+            'capability audit_write,',
+            'capability chgrp, # example comment',
+        ]
+
+        for rule in rules:
+            inc.add_raw(rule)
+
+        expected_raw = [
+            '  capability chown,',
+            '  allow capability sys_admin,',
+            '  deny capability chgrp, # example comment',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  allow capability sys_admin,',
+            '  capability chown,',
+            '',
+        ]
+
+        self.assertEqual(col.delete_duplicates(inc), 0)
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+    def test_delete_duplicates_3(self):
+        col = self._setup_testcol()
+        col.add_raw('audit capability dac_override,')
+
+        inc = capability_rules()
+        rules = [
+            'capability dac_override,',
+        ]
+
+        for rule in rules:
+            inc.add_raw(rule)
+
+        expected_raw = [
+            '  capability chown,',
+            '  allow capability sys_admin,',
+            '  deny capability chgrp, # example comment',
+            '  audit capability dac_override,',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  allow capability sys_admin,',
+            '  audit capability dac_override,',
+            '  capability chown,',
+            '',
+        ]
+
+        self.assertEqual(col.delete_duplicates(inc), 0)
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+    def test_delete_duplicates_4(self):
+        col = self._setup_testcol()
+
+        inc = capability_rules()
+        rules = [
+            'capability,',
+        ]
+
+        for rule in rules:
+            inc.add_raw(rule)
+
+        expected_raw = [
+            '  allow capability sys_admin,',  # XXX huh? should be deleted!
+            '  deny capability chgrp, # example comment',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  allow capability sys_admin,',  # XXX huh? should be deleted!
+            '',
+        ]
+
+        self.assertEqual(col.delete_duplicates(inc), 1)
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+    def test_delete_duplicates_none(self):
+        col = self._setup_testcol()
+
+        expected_raw = [
+            '  capability chown,',
+            '  allow capability sys_admin,',
+            '  deny capability chgrp, # example comment',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  allow capability sys_admin,',
+            '  capability chown,',
+            '',
+        ]
+
+        self.assertEqual(col.delete_duplicates(None), 0)
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+    def test_delete_duplicates_hasher(self):
+        col = self._setup_testcol()
+
+        expected_raw = [
+            '  capability chown,',
+            '  allow capability sys_admin,',
+            '  deny capability chgrp, # example comment',
+            '',
+        ]
+
+        expected_clean = [
+            '  deny capability chgrp, # example comment',
+            '',
+            '  allow capability sys_admin,',
+            '  capability chown,',
+            '',
+        ]
+
+        self.assertEqual(col.delete_duplicates(hasher()), 0)
+        self.assertEqual(expected_raw, col.get_raw(1))
+        self.assertEqual(expected_clean, col.get_clean(1))
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)

-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to