Add equality operator to policy.RuleDefault

There are occasions when comparing two RuleDefault objects is needed.
Rather than embedding the logic at the comparison site it's preferable
to let the object know how to compare itself to another.

Change-Id: I2eae5665fdecd6638e84f577b506314f7bc03fd3
This commit is contained in:
Andrew Laski 2016-05-25 17:01:37 -04:00
parent f5988a2596
commit ea29939194
2 changed files with 74 additions and 0 deletions

View File

@ -706,3 +706,23 @@ class RuleDefault(object):
def __str__(self):
return '"%(name)s": "%(check_str)s"' % {'name': self.name,
'check_str': self.check_str}
def __eq__(self, other):
"""Equality operator.
All check objects have a stable string representation. It is used for
comparison rather than check_str because multiple check_str's may parse
to the same check object. For instance '' and '@' are equivalent and
the parsed rule string representation for both is '@'.
The description does not play a role in the meaning of the check so it
is not considered for equality.
"""
# Name should match, check should match, and class should be equivalent
# or one should be a subclass of the other.
if (self.name == other.name and
str(self.check) == str(other.check) and
(isinstance(self, other.__class__) or
isinstance(other, self.__class__))):
return True
return False

View File

@ -719,3 +719,57 @@ class RuleDefaultTestCase(base.PolicyBaseTestCase):
def test_str(self):
opt = policy.RuleDefault(name='foo', check_str='rule:foo')
self.assertEqual('"foo": "rule:foo"', str(opt))
def test_equality_obvious(self):
opt1 = policy.RuleDefault(name='foo', check_str='rule:foo',
description='foo')
opt2 = policy.RuleDefault(name='foo', check_str='rule:foo',
description='bar')
self.assertEqual(opt1, opt2)
def test_equality_less_obvious(self):
opt1 = policy.RuleDefault(name='foo', check_str='',
description='foo')
opt2 = policy.RuleDefault(name='foo', check_str='@',
description='bar')
self.assertEqual(opt1, opt2)
def test_not_equal_check(self):
opt1 = policy.RuleDefault(name='foo', check_str='rule:foo',
description='foo')
opt2 = policy.RuleDefault(name='foo', check_str='rule:bar',
description='bar')
self.assertNotEqual(opt1, opt2)
def test_not_equal_name(self):
opt1 = policy.RuleDefault(name='foo', check_str='rule:foo',
description='foo')
opt2 = policy.RuleDefault(name='bar', check_str='rule:foo',
description='bar')
self.assertNotEqual(opt1, opt2)
def test_not_equal_class(self):
class NotRuleDefault(object):
def __init__(self, name, check_str):
self.name = name
self.check = _parser.parse_rule(check_str)
opt1 = policy.RuleDefault(name='foo', check_str='rule:foo')
opt2 = NotRuleDefault(name='foo', check_str='rule:foo')
self.assertNotEqual(opt1, opt2)
def test_equal_subclass(self):
class RuleDefaultSub(policy.RuleDefault):
pass
opt1 = policy.RuleDefault(name='foo', check_str='rule:foo')
opt2 = RuleDefaultSub(name='foo', check_str='rule:foo')
self.assertEqual(opt1, opt2)
def test_not_equal_subclass(self):
class RuleDefaultSub(policy.RuleDefault):
pass
opt1 = policy.RuleDefault(name='foo', check_str='rule:foo')
opt2 = RuleDefaultSub(name='bar', check_str='rule:foo')
self.assertNotEqual(opt1, opt2)