mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00

Annotate exceptions with ' # noqa: ERROR' Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
522 lines
22 KiB
Python
522 lines
22 KiB
Python
#!/usr/bin/python3
|
|
# ----------------------------------------------------------------------
|
|
# Copyright (C) 2015 Christian Boltz <apparmor@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 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 collections import namedtuple
|
|
|
|
from apparmor.common import AppArmorBug, AppArmorException
|
|
# from apparmor.logparser import ReadLog
|
|
from apparmor.rule.rlimit import RlimitRule, RlimitRuleset, split_unit
|
|
from apparmor.translations import init_translation
|
|
from common_test import AATest, setup_all_loops
|
|
|
|
_ = init_translation()
|
|
|
|
exp = namedtuple(
|
|
'exp', ('audit', 'allow_keyword', 'deny', 'comment', 'rlimit', 'value', 'all_values'))
|
|
|
|
# --- tests for single RlimitRule --- #
|
|
|
|
|
|
class RlimitTest(AATest):
|
|
def _compare_obj(self, obj, expected):
|
|
self.assertEqual(expected.allow_keyword, obj.allow_keyword)
|
|
self.assertEqual(expected.audit, obj.audit)
|
|
self.assertEqual(expected.rlimit, obj.rlimit)
|
|
self.assertEqual(expected.value, obj.value)
|
|
self.assertEqual(expected.all_values, obj.all_values)
|
|
self.assertEqual(expected.deny, obj.deny)
|
|
self.assertEqual(expected.comment, obj.comment)
|
|
|
|
|
|
class RlimitTestParse(RlimitTest):
|
|
tests = (
|
|
# rawrule audit allow deny comment rlimit value all/infinity?
|
|
('set rlimit as <= 2047MB,', exp(False, False, False, '', 'as', '2047MB', False)),
|
|
('set rlimit as <= 2047 MB,', exp(False, False, False, '', 'as', '2047 MB', False)),
|
|
('set rlimit cpu <= 1024,', exp(False, False, False, '', 'cpu', '1024', False)),
|
|
('set rlimit stack <= 1024GB,', exp(False, False, False, '', 'stack', '1024GB', False)),
|
|
('set rlimit stack <= 1024 GB,', exp(False, False, False, '', 'stack', '1024 GB', False)),
|
|
('set rlimit rtprio <= 10, # comment', exp(False, False, False, ' # comment', 'rtprio', '10', False)),
|
|
('set rlimit core <= 44444KB,', exp(False, False, False, '', 'core', '44444KB', False)),
|
|
('set rlimit core <= 44444 KB,', exp(False, False, False, '', 'core', '44444 KB', False)),
|
|
('set rlimit rttime <= 60ms,', exp(False, False, False, '', 'rttime', '60ms', False)),
|
|
('set rlimit cpu <= infinity,', exp(False, False, False, '', 'cpu', None, True)),
|
|
('set rlimit nofile <= 256,', exp(False, False, False, '', 'nofile', '256', False)),
|
|
('set rlimit data <= 4095KB,', exp(False, False, False, '', 'data', '4095KB', False)),
|
|
('set rlimit cpu <= 12, # cmt', exp(False, False, False, ' # cmt', 'cpu', '12', False)),
|
|
('set rlimit ofile <= 1234,', exp(False, False, False, '', 'ofile', '1234', False)),
|
|
('set rlimit msgqueue <= 4444,', exp(False, False, False, '', 'msgqueue', '4444', False)),
|
|
('set rlimit nice <= -10,', exp(False, False, False, '', 'nice', '-10', False)),
|
|
('set rlimit rttime <= 60minutes,', exp(False, False, False, '', 'rttime', '60minutes', False)),
|
|
('set rlimit fsize <= 1023MB,', exp(False, False, False, '', 'fsize', '1023MB', False)),
|
|
('set rlimit nproc <= 1,', exp(False, False, False, '', 'nproc', '1', False)),
|
|
('set rlimit rss <= infinity, # cmt', exp(False, False, False, ' # cmt', 'rss', None, True)),
|
|
('set rlimit memlock <= 10240,', exp(False, False, False, '', 'memlock', '10240', False)),
|
|
('set rlimit sigpending <= 42,', exp(False, False, False, '', 'sigpending', '42', False)),
|
|
)
|
|
|
|
def _run_test(self, rawrule, expected):
|
|
self.assertTrue(RlimitRule.match(rawrule))
|
|
obj = RlimitRule.create_instance(rawrule)
|
|
self.assertEqual(rawrule.strip(), obj.raw_rule)
|
|
self._compare_obj(obj, expected)
|
|
|
|
|
|
class RlimitTestParseInvalid(RlimitTest):
|
|
tests = (
|
|
('set rlimit,', AppArmorException), # missing parts
|
|
('set rlimit <= 5,', AppArmorException),
|
|
('set rlimit cpu <= ,', AppArmorException),
|
|
('set rlimit cpu <= "",', AppArmorBug), # evil quoting trick
|
|
('set rlimit foo <= 5,', AppArmorException), # unknown rlimit
|
|
('set rlimit rttime <= 60m,', AppArmorException), # 'm' could mean 'ms' or 'minutes'
|
|
('set rlimit cpu <= 20ms,', AppArmorException), # cpu doesn't support 'ms'...
|
|
('set rlimit cpu <= 20us,', AppArmorException), # ... or 'us'
|
|
('set rlimit nice <= 20MB,', AppArmorException), # invalid unit for this rlimit type
|
|
('set rlimit cpu <= 20MB,', AppArmorException),
|
|
('set rlimit data <= 20seconds,', AppArmorException),
|
|
('set rlimit locks <= 20seconds,', AppArmorException),
|
|
)
|
|
|
|
def _run_test(self, rawrule, expected):
|
|
# self.assertFalse(RlimitRule.match(rawrule)) # the main regex isn't very strict
|
|
with self.assertRaises(expected):
|
|
RlimitRule.create_instance(rawrule)
|
|
|
|
|
|
class RlimitTestParseFromLog(RlimitTest):
|
|
pass
|
|
# def test_net_from_log(self):
|
|
# parser = ReadLog('', '', '')
|
|
#
|
|
# event = 'type=AVC ...'
|
|
#
|
|
# parsed_event = parser.parse_event(event)
|
|
#
|
|
# self.assertEqual(parsed_event, {
|
|
# ...
|
|
# })
|
|
#
|
|
# obj = RlimitRule(RlimitRule.ALL, parsed_event['name2'], log_event=parsed_event)
|
|
#
|
|
# # audit allow deny comment rlimit value all?
|
|
# expected = exp(False, False, False, '', None, '/foo/rename', False)
|
|
#
|
|
# self._compare_obj(obj, expected)
|
|
#
|
|
# self.assertEqual(obj.get_raw(1), ' rlimit -> /foo/rename,')
|
|
|
|
|
|
class RlimitFromInit(RlimitTest):
|
|
tests = (
|
|
# RlimitRule object audit allow deny comment rlimit value all/infinity?
|
|
(RlimitRule('as', '2047MB'), exp(False, False, False, '', 'as', '2047MB', False)),
|
|
(RlimitRule('as', '2047 MB'), exp(False, False, False, '', 'as', '2047 MB', False)),
|
|
(RlimitRule('cpu', '1024'), exp(False, False, False, '', 'cpu', '1024', False)),
|
|
(RlimitRule('rttime', '60minutes'), exp(False, False, False, '', 'rttime', '60minutes', False)),
|
|
(RlimitRule('nice', '-10'), exp(False, False, False, '', 'nice', '-10', False)),
|
|
(RlimitRule('rss', RlimitRule.ALL), exp(False, False, False, '', 'rss', None, True)),
|
|
)
|
|
|
|
def _run_test(self, obj, expected):
|
|
self._compare_obj(obj, expected)
|
|
|
|
|
|
class InvalidRlimitInit(AATest):
|
|
tests = (
|
|
# init params expected exception
|
|
(('as', ''), AppArmorBug), # empty value
|
|
(('', '1024'), AppArmorException), # empty rlimit
|
|
((' ', '1024'), AppArmorException), # whitespace rlimit
|
|
(('as', ' '), AppArmorBug), # whitespace value
|
|
(('xyxy', '1024'), AppArmorException), # invalid rlimit
|
|
((dict(), '1024'), AppArmorBug), # wrong type for rlimit
|
|
((None, '1024'), AppArmorBug), # wrong type for rlimit
|
|
(('as', dict()), AppArmorBug), # wrong type for value
|
|
(('as', None), AppArmorBug), # wrong type for value
|
|
(('cpu', '100xy2'), AppArmorException), # invalid unit
|
|
)
|
|
|
|
def _run_test(self, params, expected):
|
|
with self.assertRaises(expected):
|
|
RlimitRule(*params)
|
|
|
|
def test_missing_params_1(self):
|
|
with self.assertRaises(TypeError):
|
|
RlimitRule()
|
|
|
|
def test_missing_params_2(self):
|
|
with self.assertRaises(TypeError):
|
|
RlimitRule('as')
|
|
|
|
def test_allow_keyword(self):
|
|
with self.assertRaises(AppArmorBug):
|
|
RlimitRule('as', '1024MB', allow_keyword=True)
|
|
|
|
def test_deny_keyword(self):
|
|
with self.assertRaises(AppArmorBug):
|
|
RlimitRule('as', '1024MB', deny=True)
|
|
|
|
def test_audit_keyword(self):
|
|
with self.assertRaises(AppArmorBug):
|
|
RlimitRule('as', '1024MB', audit=True)
|
|
|
|
|
|
class InvalidRlimitTest(AATest):
|
|
def _check_invalid_rawrule(self, rawrule):
|
|
obj = None
|
|
self.assertFalse(RlimitRule.match(rawrule))
|
|
with self.assertRaises(AppArmorException):
|
|
obj = RlimitRule.create_instance(rawrule)
|
|
|
|
self.assertIsNone(obj, 'RlimitRule handed back an object unexpectedly')
|
|
|
|
def test_invalid_net_missing_comma(self):
|
|
self._check_invalid_rawrule('rlimit') # missing comma
|
|
|
|
def test_invalid_net_non_RlimitRule(self):
|
|
self._check_invalid_rawrule('dbus,') # not a rlimit rule
|
|
|
|
def test_empty_net_data_1(self):
|
|
obj = RlimitRule('as', '1024MB')
|
|
obj.rlimit = ''
|
|
# no rlimit set, and ALL not set
|
|
with self.assertRaises(AppArmorBug):
|
|
obj.get_clean(1)
|
|
|
|
def test_empty_net_data_2(self):
|
|
obj = RlimitRule('as', '1024MB')
|
|
obj.value = ''
|
|
# no value set, and ALL not set
|
|
with self.assertRaises(AppArmorBug):
|
|
obj.get_clean(1)
|
|
|
|
|
|
class WriteRlimitTest(AATest):
|
|
tests = (
|
|
# raw rule clean rule
|
|
(' set rlimit cpu <= 1024 , # foo ', 'set rlimit cpu <= 1024, # foo'),
|
|
(' set rlimit stack <= 1024GB ,', 'set rlimit stack <= 1024GB,'),
|
|
(' set rlimit rttime <= 100ms , # foo bar', 'set rlimit rttime <= 100ms, # foo bar'),
|
|
(' set rlimit cpu <= infinity , ', 'set rlimit cpu <= infinity,'),
|
|
(' set rlimit msgqueue <= 4444 , ', 'set rlimit msgqueue <= 4444,'),
|
|
(' set rlimit nice <= 5 , # foo bar', 'set rlimit nice <= 5, # foo bar'),
|
|
(' set rlimit nice <= -5 , # cmt', 'set rlimit nice <= -5, # cmt'),
|
|
)
|
|
|
|
def _run_test(self, rawrule, expected):
|
|
self.assertTrue(RlimitRule.match(rawrule))
|
|
obj = RlimitRule.create_instance(rawrule)
|
|
clean = obj.get_clean()
|
|
raw = obj.get_raw()
|
|
|
|
self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
|
|
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
|
|
|
|
def test_write_manually(self):
|
|
obj = RlimitRule('as', '1024MB')
|
|
|
|
expected = ' set rlimit as <= 1024MB,'
|
|
|
|
self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule')
|
|
self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule')
|
|
|
|
|
|
class RlimitCoveredTest(AATest):
|
|
def _run_test(self, param, expected):
|
|
obj = RlimitRule.create_instance(self.rule)
|
|
check_obj = RlimitRule.create_instance(param)
|
|
|
|
self.assertTrue(RlimitRule.match(param))
|
|
|
|
self.assertEqual(
|
|
obj.is_equal(check_obj), expected[0],
|
|
'Mismatch in is_equal, expected {}'.format(expected[0]))
|
|
self.assertEqual(
|
|
obj.is_equal(check_obj, True), expected[1],
|
|
'Mismatch in is_equal/strict, expected {}'.format(expected[1]))
|
|
|
|
self.assertEqual(
|
|
obj.is_covered(check_obj), expected[2],
|
|
'Mismatch in is_covered, expected {}'.format(expected[2]))
|
|
self.assertEqual(
|
|
obj.is_covered(check_obj, True, True), expected[3],
|
|
'Mismatch in is_covered/exact, expected {}'.format(expected[3]))
|
|
|
|
|
|
class RlimitCoveredTest_01(RlimitCoveredTest):
|
|
rule = 'set rlimit cpu <= 150,'
|
|
|
|
tests = (
|
|
# rule equal strict equal covered covered exact
|
|
('set rlimit as <= 100MB,', (False, False, False, False)),
|
|
('set rlimit rttime <= 150,', (False, False, False, False)),
|
|
('set rlimit cpu <= 100,', (False, False, True, True)),
|
|
('set rlimit cpu <= 150,', (True, True, True, True)),
|
|
('set rlimit cpu <= 300,', (False, False, False, False)),
|
|
('set rlimit cpu <= 10seconds,', (False, False, True, True)),
|
|
('set rlimit cpu <= 150seconds,', (True, False, True, True)),
|
|
('set rlimit cpu <= 300seconds,', (False, False, False, False)),
|
|
('set rlimit cpu <= 1minutes,', (False, False, True, True)),
|
|
('set rlimit cpu <= 1min,', (False, False, True, True)),
|
|
('set rlimit cpu <= 3minutes,', (False, False, False, False)),
|
|
('set rlimit cpu <= 1hour,', (False, False, False, False)),
|
|
('set rlimit cpu <= 2 days,', (False, False, False, False)),
|
|
('set rlimit cpu <= 1 week,', (False, False, False, False)),
|
|
)
|
|
|
|
|
|
class RlimitCoveredTest_02(RlimitCoveredTest):
|
|
rule = 'set rlimit data <= 4MB,'
|
|
|
|
tests = (
|
|
# rule equal strict equal covered covered exact
|
|
('set rlimit data <= 100,', (False, False, True, True)),
|
|
('set rlimit data <= 2KB,', (False, False, True, True)),
|
|
('set rlimit data <= 2MB,', (False, False, True, True)),
|
|
('set rlimit data <= 4194304,', (True, False, True, True)),
|
|
('set rlimit data <= 4096KB,', (True, False, True, True)),
|
|
('set rlimit data <= 4MB,', (True, True, True, True)),
|
|
('set rlimit data <= 4 MB,', (True, False, True, True)),
|
|
('set rlimit data <= 6MB,', (False, False, False, False)),
|
|
('set rlimit data <= 6 MB,', (False, False, False, False)),
|
|
('set rlimit data <= 1GB,', (False, False, False, False)),
|
|
)
|
|
|
|
|
|
class RlimitCoveredTest_03(RlimitCoveredTest):
|
|
rule = 'set rlimit nice <= -1,'
|
|
|
|
tests = (
|
|
# rule equal strict equal covered covered exact
|
|
('set rlimit nice <= 5,', (False, False, True, True)),
|
|
('set rlimit nice <= 0,', (False, False, True, True)),
|
|
('set rlimit nice <= -1,', (True, True, True, True)),
|
|
('set rlimit nice <= -3,', (False, False, False, False)),
|
|
)
|
|
|
|
|
|
class RlimitCoveredTest_04(RlimitCoveredTest):
|
|
rule = 'set rlimit locks <= 42,'
|
|
|
|
tests = (
|
|
# rule equal strict equal covered covered exact
|
|
('set rlimit locks <= 20,', (False, False, True, True)),
|
|
('set rlimit locks <= 40,', (False, False, True, True)),
|
|
('set rlimit locks <= 42,', (True, True, True, True)),
|
|
('set rlimit locks <= 60,', (False, False, False, False)),
|
|
('set rlimit locks <= infinity,', (False, False, False, False)),
|
|
)
|
|
|
|
|
|
class RlimitCoveredTest_05(RlimitCoveredTest):
|
|
rule = 'set rlimit locks <= infinity,'
|
|
|
|
tests = (
|
|
# rule equal strict equal covered covered exact
|
|
('set rlimit locks <= 20,', (False, False, True, True)),
|
|
('set rlimit cpu <= 40,', (False, False, False, False)),
|
|
('set rlimit locks <= infinity,', (True, True, True, True)),
|
|
)
|
|
|
|
|
|
class RlimitCoveredTest_Invalid(AATest):
|
|
def test_borked_obj_is_covered_1(self):
|
|
obj = RlimitRule.create_instance('set rlimit cpu <= 1024,')
|
|
|
|
testobj = RlimitRule('cpu', '1024')
|
|
testobj.rlimit = ''
|
|
|
|
with self.assertRaises(AppArmorBug):
|
|
obj.is_covered(testobj)
|
|
|
|
def test_borked_obj_is_covered_2(self):
|
|
obj = RlimitRule.create_instance('set rlimit cpu <= 1024,')
|
|
|
|
testobj = RlimitRule('cpu', '1024')
|
|
testobj.value = ''
|
|
|
|
with self.assertRaises(AppArmorBug):
|
|
obj.is_covered(testobj)
|
|
|
|
def test_invalid_is_covered(self):
|
|
raw_rule = 'set rlimit cpu <= 1024,'
|
|
|
|
class SomeOtherClass(RlimitRule):
|
|
pass
|
|
|
|
obj = RlimitRule.create_instance(raw_rule)
|
|
testobj = SomeOtherClass.create_instance(raw_rule) # different type
|
|
with self.assertRaises(AppArmorBug):
|
|
obj.is_covered(testobj)
|
|
|
|
def test_invalid_is_equal(self):
|
|
raw_rule = 'set rlimit cpu <= 1024,'
|
|
|
|
class SomeOtherClass(RlimitRule):
|
|
pass
|
|
|
|
obj = RlimitRule.create_instance(raw_rule)
|
|
testobj = SomeOtherClass.create_instance(raw_rule) # different type
|
|
with self.assertRaises(AppArmorBug):
|
|
obj.is_equal(testobj)
|
|
|
|
|
|
class RlimitLogprofHeaderTest(AATest):
|
|
tests = (
|
|
('set rlimit cpu <= infinity,', [_('Rlimit'), 'cpu', _('Value'), 'infinity']),
|
|
('set rlimit as <= 200MB,', [_('Rlimit'), 'as', _('Value'), '200MB']),
|
|
('set rlimit rttime <= 200ms,', [_('Rlimit'), 'rttime', _('Value'), '200ms']),
|
|
('set rlimit nproc <= 1,', [_('Rlimit'), 'nproc', _('Value'), '1']),
|
|
)
|
|
|
|
def _run_test(self, params, expected):
|
|
obj = RlimitRule.create_instance(params)
|
|
self.assertEqual(obj.logprof_header(), expected)
|
|
|
|
|
|
# --- tests for RlimitRuleset --- #
|
|
|
|
class RlimitRulesTest(AATest):
|
|
def test_empty_ruleset(self):
|
|
ruleset = RlimitRuleset()
|
|
ruleset_2 = RlimitRuleset()
|
|
self.assertEqual([], ruleset.get_raw(2))
|
|
self.assertEqual([], ruleset.get_clean(2))
|
|
self.assertEqual([], ruleset_2.get_raw(2))
|
|
self.assertEqual([], ruleset_2.get_clean(2))
|
|
|
|
def test_ruleset_1(self):
|
|
ruleset = RlimitRuleset()
|
|
rules = [
|
|
' set rlimit cpu <= 100,',
|
|
' set rlimit as <= 50MB,',
|
|
]
|
|
|
|
expected_raw = [
|
|
'set rlimit cpu <= 100,',
|
|
'set rlimit as <= 50MB,',
|
|
'',
|
|
]
|
|
|
|
expected_clean = [
|
|
'set rlimit as <= 50MB,',
|
|
'set rlimit cpu <= 100,',
|
|
'',
|
|
]
|
|
|
|
for rule in rules:
|
|
ruleset.add(RlimitRule.create_instance(rule))
|
|
|
|
self.assertEqual(expected_raw, ruleset.get_raw())
|
|
self.assertEqual(expected_clean, ruleset.get_clean())
|
|
|
|
|
|
class RlimitGlobTestAATest(AATest):
|
|
def setUp(self):
|
|
self.ruleset = RlimitRuleset()
|
|
|
|
def test_glob_1(self):
|
|
with self.assertRaises(AppArmorBug):
|
|
self.ruleset.get_glob('set rlimit cpu <= 100,')
|
|
|
|
# not supported or used yet, glob behaviour not decided yet
|
|
# def test_glob_2(self):
|
|
# self.assertEqual(self.ruleset.get_glob('rlimit /foo -> /bar,'), 'rlimit -> /bar,')
|
|
|
|
def test_glob_ext(self):
|
|
with self.assertRaises(NotImplementedError):
|
|
# get_glob_ext is not available for rlimit rules
|
|
self.ruleset.get_glob_ext('set rlimit cpu <= 100,')
|
|
|
|
|
|
class RlimitDeleteTestAATest(AATest):
|
|
# no de-duplication tests for rlimit - de-duplication consists of is_covered() (which we already test) and
|
|
# code from BaseRuleset (which is already tested in the capability, network and change_profile tests).
|
|
# Therefore no need to test it once more ;-)
|
|
pass
|
|
|
|
|
|
# --- other tests --- #
|
|
class RlimitSplit_unitTest(AATest):
|
|
tests = (
|
|
('40MB', (40, 'MB')),
|
|
('40 MB', (40, 'MB')),
|
|
('40', (40, '')),
|
|
)
|
|
|
|
def _run_test(self, params, expected):
|
|
self.assertEqual(split_unit(params), expected)
|
|
|
|
def test_invalid_split_unit(self):
|
|
with self.assertRaises(AppArmorBug):
|
|
split_unit('MB')
|
|
|
|
|
|
class RlimitSize_to_intTest(AATest):
|
|
def AASetup(self):
|
|
self.obj = RlimitRule('cpu', '1')
|
|
|
|
tests = (
|
|
('40GB', 40 * 1024 * 1024 * 1024),
|
|
('40MB', 41943040),
|
|
('40KB', 40960),
|
|
('40', 40),
|
|
)
|
|
|
|
def _run_test(self, params, expected):
|
|
self.assertEqual(self.obj.size_to_int(params), expected)
|
|
|
|
def test_invalid_size_to_int_01(self):
|
|
with self.assertRaises(AppArmorException):
|
|
self.obj.size_to_int('20mice')
|
|
|
|
|
|
class RlimitTime_to_intTest(AATest):
|
|
def AASetup(self):
|
|
self.obj = RlimitRule('cpu', '1')
|
|
|
|
tests = (
|
|
('40', 0.00004),
|
|
('30us', 0.00003),
|
|
('40ms', 0.04),
|
|
('40seconds', 40),
|
|
('2minutes', 2 * 60),
|
|
('2hours', 2 * 60 * 60),
|
|
('1 day', 1 * 60 * 60 * 24),
|
|
('2 weeks', 2 * 60 * 60 * 24 * 7),
|
|
)
|
|
|
|
def _run_test(self, params, expected):
|
|
self.assertEqual(self.obj.time_to_int(params, 'us'), expected)
|
|
|
|
def test_with_seconds_as_default(self):
|
|
self.assertEqual(self.obj.time_to_int('40', 'seconds'), 40)
|
|
|
|
def test_with_ms_as_default(self):
|
|
self.assertEqual(self.obj.time_to_int('40', 'ms'), 0.04)
|
|
|
|
def test_with_us_as_default(self):
|
|
self.assertEqual(self.obj.time_to_int('30', 'us'), 0.00003)
|
|
|
|
def test_invalid_time_to_int(self):
|
|
with self.assertRaises(AppArmorException):
|
|
self.obj.time_to_int('20mice', 'seconds')
|
|
|
|
|
|
setup_all_loops(__name__)
|
|
if __name__ == '__main__':
|
|
unittest.main(verbosity=1)
|