diff --git a/nornir/core/filter.py b/nornir/core/filter.py index 976ad131..c6507fa6 100644 --- a/nornir/core/filter.py +++ b/nornir/core/filter.py @@ -22,6 +22,15 @@ def __or__(self, other: F_BASE) -> "OR": def __repr__(self) -> str: return "( {} {} {} )".format(self.op1, self.__class__.__name__, self.op2) + def __eq__(self, other: object) -> bool: + if not isinstance(other, F_OP_BASE): + # don't compare against unrelated types + return NotImplemented + return self.__class__ == other.__class__ and ( + (self.op1 == other.op1 and self.op2 == other.op2) + or (self.op1 == other.op2 and self.op2 == other.op1) + ) + class AND(F_OP_BASE): def __call__(self, host: Host) -> bool: @@ -54,6 +63,12 @@ def __invert__(self) -> "F": def __repr__(self) -> str: return "".format(self.filters) + def __eq__(self, other: object) -> bool: + if not isinstance(other, F): + # don't compare against unrelated types + return NotImplemented + return self.__class__ == other.__class__ and self.filters == other.filters + @staticmethod def _verify_rules(data: Any, rule: List[str], value: Any) -> bool: if len(rule) > 1: diff --git a/tests/core/test_filter.py b/tests/core/test_filter.py index b8c1bd58..7599e3f6 100644 --- a/tests/core/test_filter.py +++ b/tests/core/test_filter.py @@ -1,4 +1,5 @@ -from nornir.core.filter import F +import pytest +from nornir.core.filter import F, AND, OR class Test(object): @@ -170,3 +171,27 @@ def test_eq__on_not_existing_key(self, nornir): filtered = sorted(list((nornir.inventory.filter(f).hosts.keys()))) assert filtered == [] + + @pytest.mark.parametrize( + "filter_a,filter_b", + [ + (F(), F()), + (F(site="site1") & F(role="www"), AND(F(site="site1"), F(role="www"))), + (F(site="site1") & F(role="www"), AND(F(role="www"), F(site="site1"))), + (F(site="site1") | F(role="www"), OR(F(site="site1"), F(role="www"))), + (F(site="site1") | F(role="www"), OR(F(role="www"), F(site="site1"))), + ], + ) + def test_compare_filter_equal(self, filter_a, filter_b): + assert filter_a == filter_b + + @pytest.mark.parametrize( + "filter_a,filter_b", + [ + (OR(F(site="site1"), F(role="www")), AND(F(site="site1"), F(role="www"))), + (F(site="site1"), F(role="www")), + (F(site="site1"), ~F(site="site1")), + ], + ) + def test_compare_filter_not_equal(self, filter_a, filter_b): + assert filter_a != filter_b